如何在c中将字符串标记为int数组?

任何人都有关于从每行文本文件中读取序列号并将其解析为C中的数组的任何事情?

我在文件中有什么:

12 3 45 6 7 8 3 5 6 7 7 0 -1 4 5 

我想要的程序:

 array1[] = {12, 3, 45, 6, 7, 8}; array2[] = {3, 5, 6, 7}; array3[] = {7, 0, -1, 4, 5}; 

我已经通过几种方式阅读它,但唯一的问题是我想要每行标记它。 谢谢。

以下代码将一次读取一行文件

 char line[80] FILE* fp = fopen("data.txt","r"); while(fgets(line,1,fp) != null) { // do something } fclose(fp); 

然后,您可以使用strtok()和sscanf()将输入标记为输入,以将文本转换为数字。

从sscanf的MSDN页面:

这些函数[sscanf和swscanf]中的每一个都返回成功转换和分配的字段数; 返回值不包括已读但未分配的字段。 返回值0表示未分配任何字段。 如果出现错误,或者在第一次转换之前到达字符串的结尾,则返回值为EOF。

以下代码将字符串转换为整数数组。 显然,对于可变长度数组,您需要一个列表或一些扫描输入两次以确定数组在实际解析之前的长度。

 char tokenstring[] = "12 23 3 4 5"; char seps[] = " "; char* token; int var; int input[5]; int i = 0; token = strtok (tokenstring, seps); while (token != NULL) { sscanf (token, "%d", &var); input[i++] = var; token = strtok (NULL, seps); } 

把:

 char seps[] = " ,\t\n"; 

将允许输入更灵活。

我不得不进行搜索以提醒自己语法 – 我在MSDN中找到它

我要做的是做一个这样的函数:

 size_t read_em(FILE *f, int **a); 

在函数中,为指针*a分配一些内存,然后从f开始读取数字并将它们存储在*a 。 当您遇到换行符时,只需返回您存储在*a的元素数。 然后,像这样调用它:

 int *a = NULL; FILE *f = fopen("Somefile.txt", "r"); size_t len = read_em(f, &a); // now a is an array, and len is the number of elements in that array 

有用的function:

  • malloc()分配一个数组。
  • realloc()扩展malloc() ed数组
  • fgets()读取一行文本(或尽可能多地存储)。
  • sscanf()将字符串中的数据(例如fgets()返回的字符串)读入其他变量(例如malloc()创建的int数组 – 提示提示)

当字段数量可变时,我强烈建议不要使用sscanf和朋友。 使用strtok和atoi 。 只要确保很好地阅读strtok手册页,我认识的许多程序员在开始时发现它的语法有点令人惊讶。 另请注意,strtok将修改输入字符串,因此您可能希望处理副本。

以下代码可能是您正在寻找的。 希望您在评论时不需要太多描述,但如果您有任何疑问,请随时提出。

它基本上使用fgets循环读取每一行和strtok以将该行分成字段。 它构造一个包含实际数据的整数数组的链接列表 – 您可以看到在转储表的末尾的代码中使用该链表。

它还有一种方法可以处理输入文件中任意大小的行而不会出现缓冲区溢出(当然受内存限制)。 请记住, strtok只需要线上每个字段之间的一个空格,尽管可以重新编码以处理多个空格甚至任何数量的空白区域。 我保持这一点简单,因为代码已经变得有点大了:-)

atoi函数用于将每行上的单个单词转换为整数。 如果你想对它们进行错误检查,我会调用你自己的变体,它也检查单词中的所有字符都是数字。

使用您的输入文件:

 12 3 45 6 7 8 3 5 6 7 7 0 -1 4 5 

它产生的输出方式如下:

 0x97b5170, size = 6: 12 3 45 6 7 8 0x97b51d0, size = 4: 3 5 6 7 0x97b51e0, size = 5: 7 0 -1 4 5 

这是产生该输出的代码:

 #include  #include  #include  #include  // This is the linked list of integer arrays. typedef struct _tIntArray { int size; int *array; struct _tIntArray *next; } tIntArray; static tIntArray *first = NULL; static tIntArray *last = NULL; // Add a line of integers as a node. static int addNode (char *str) { tIntArray *curr; // pointers for new integer array. char *word; // word within string. char *tmpStr; // temp copy of buffer. int fldCnt; // field count for line. int i; // Count number of fields. if ((tmpStr = strdup (str)) == NULL) { printf ("Cannot allocate duplicate string (%d).\n", errno); return 1; } fldCnt = 0; for (word = strtok (tmpStr, " "); word; word = strtok (NULL, " ")) fldCnt++; free (tmpStr); 

  // Create new linked list node. if ((curr = malloc (sizeof (tIntArray))) == NULL) { printf ("Cannot allocate integer array node (%d).\n", errno); return 1; } curr->size = fldCnt; if ((curr->array = malloc (fldCnt * sizeof (int))) == NULL) { printf ("Cannot allocate integer array (%d).\n", errno); free (curr); return 1; } curr->next = NULL; for (i = 0, word = strtok (str, " "); word; word = strtok (NULL, " ")) curr->array[i++] = atoi (word); if (last == NULL) first = last = curr; else { last->next = curr; last = curr; } return 0; } 

 int main(void) { int lineSz; // current line size. char *buff; // buffer to hold line. FILE *fin; // input file handle. long offset; // offset for re-allocating line buffer. tIntArray *curr; // pointers for new integer array. int i; // Open file. if ((fin = fopen ("qq.in", "r")) == NULL) { printf ("Cannot open qq.in, errno = %d\n", errno); return 1; } // Allocate initial line. lineSz = 2; if ((buff = malloc (lineSz+1)) == NULL) { printf ("Cannot allocate initial memory, errno = %d.\n", errno); return 1; } // Loop forever. while (1) { // Save offset in case we need to re-read. offset = ftell (fin); 

  // Get line, exit if end of file. if (fgets (buff, lineSz, fin) == NULL) break; // If no newline, assume buffer wasn't big enough. if (buff[strlen(buff)-1] != '\n') { // Get bigger buffer and seek back to line start and retry. free (buff); lineSz += 3; if ((buff = malloc (lineSz+1)) == NULL) { printf ("Cannot allocate extra memory, errno = %d.\n", errno); return 1; } if (fseek (fin, offset, SEEK_SET) != 0) { printf ("Cannot seek, errno = %d.\n", errno); return 1; } continue; } // Remove newline and process. buff[strlen(buff)-1] = '\0'; if (addNode (buff) != 0) return 1; } 

  // Dump table for debugging. for (curr = first; curr != NULL; curr = curr->next) { printf ("%p, size = %d:\n ", curr, curr->size); for (i = 0; i < curr->size; i++) printf (" %d", curr->array[i]); printf ("\n"); } // Free resources and exit. free (buff); fclose (fin); return 0; } 

您的文件是否具有特定数量的行,或者您是否需要能够将任意数字读入随机数组?

这是逐行读取文件的代码。

 #include  int main() { char *inname = "test.txt"; FILE *infile; char line_buffer[BUFSIZ]; infile = fopen(inname, "r"); if (!infile) { printf("Couldn't open file %s for reading.\n", inname); return 0; } while (fgets(line_buffer, sizeof(line_buffer), infile)) { // process line } return 0; } 

您可以使用sscanf或任何许多标记化/转换函数来提取数字。 BUFSIZstdio.h中的一个很好的常量,旨在使目标系统上的流I / O高效。

使用strtol()来解析每一行:

 #include  #include  #include  int main(void) { static char buffer[1024]; static long values[256]; while(fgets(buffer, sizeof buffer, stdin)) { char *current = buffer; size_t i = 0; while(*current && *current != '\n' && i < sizeof values / sizeof *values) { char *tail = NULL; errno = 0; values[i] = strtol(current, &tail, 0); if(errno || tail == current) { fprintf(stderr, "failed to parse %s\n", current); break; } ++i, current = tail; } // process values printf("read %i values\n", i); } }