1

我的任务是读取两个数字字符串并将它们保存在不同的数组中。我决定使用 scanf 函数,但程序只能读取第一个字符串。这是我的错误代码。

int main()
{

    int firstArray[50], secondArray[50], i, j;

    /* fill an array with 0 */
    for(i=0; i<50; ++i)
    {
        firstArray[i]=secondArray[i]=0;
    }

    i=j=0;

    while((scanf("%d", &firstArray[i]))== 1) { ++i; }
    while((scanf("%d", &secondArray[j]))== 1) { ++j; }

    /* Print this. */
    for(i = 0; i < 20; ++i)
    {
        printf("%d ", firstArray[i]);
    }
    putchar('\n');

    for(j = 0; j < 20; ++j)
    {
        printf("%d ", secondArray[j]);
    }

    return 0;
}

我只是不明白 scanf 函数是如何工作的。有人可以解释一下吗?

4

4 回答 4

0

scanf忽略空白字符(包括换行符)。firstArray因此,如果您没有“非空白”分隔符,您的扫描将读取整个输入。

如果文件/数据;位于第一行的末尾,它将停止读取到firstArray那里,并且永远不会读取任何内容secondArray- 因为您永远不会使用;.

/* This will never be 1 as ; is blocking */
while((scanf("%d", &secondArray[i])) == 1) { 

所以:如果你与 ie 分开,;你必须在读入secondArray.

您还可以添加以下内容:

char c;

/* this can be done more tidy, but only as concept */
while((scanf("%d", &firstArray[i])) == 1 && i < max) {
    ++i;
    if ((c = getchar()) == '\n' || c == ';')
        break;
}

此外,您可以说,而不是通过循环将数组初始化为 0:

int firstArray[50] = {0}; /* This set every item to 0 */

还要注意确保您不超过 50 的限制。

于 2012-04-15T09:34:51.043 回答
0

你不能用它scanf来做到这一点。

阅读文档

观察:

  1. scanf如果您输入一个数字,您的循环将永远运行
  2. 没有检查阵列的大小 50 限制
  3. 如果您按return然后它会忽略该行,因为与您的模式不匹配
  4. 如果您输入一个字母,则模式不匹配并且循环中断

因此,请使用其他功能,gets也许atoistrtol。并记住检查数组的大小限制为 50。

于 2012-04-15T09:24:18.733 回答
0

实际上,C 的数组有一个特殊点。

尽管您声明了数组的大小。说int arr[5];您可以存储超过5大小的值。它不会显示任何错误,但会导致未定义的行为(可能会覆盖其他变量)。

请参考这个问题:数组大小小于号。存储在其中的元素

在你的情况下,那是你的问题。编译器从未超过第一个 while 语句。因此,您没有得到任何输出。事实上,它甚至还没有编译整个代码!

while((scanf("%d", &firstArray[i]))== 1) { ++i; }

所以,你可以这样写这个 while 语句:

while(  scanf("%d", &firstArray[i]) ==1 && i<50 )  
    i++;

要不然:

while(i<50 )
{
        scanf("%d", &firstArray[i]);             
        i++;
}

要不然:

for (i=0; i<50; i++)
    scanf("%d", &firstArray[i]);
于 2012-04-15T09:50:37.967 回答
0

你说一串数字然后你读%d。该格式扫描输入以查找表示整数(有符号)值的最长序列。第一个 while 循环消耗了两个“数字字符串”。

编辑而不是“数字字符串”,您应该说“整数字符串”。在这种情况下,它有点微妙,因为第一个 while 可以消耗所有整数,除非它们被一些不是可能的整数(例如 a ;)分隔。

因此,要使以下内容起作用,您必须将两个“行”与无法解析为整数且不被视为“白色字符”的内容分开。不是更好的解决方案,而是一种可能的解决方案。

#include <stdio.h>
#include <ctype.h>

int main()
{

  int firstArray[50] = {0};
  int secondArray[50] = {0};
  int i, j, l1, l2;
  int tmp;

  i = j = 0;

  // read integers, but not more than size of array
  while( scanf("%d", &firstArray[i]) == 1 && i < sizeof(firstArray) ) { 
    ++i; 
  }

  // consume non digits
  for(tmp = getchar(); tmp != EOF && !isdigit(tmp); tmp = getchar());
  // on EOF you should exit and stop processing;
  // we read one more char, push it back if it was a digit
  if (isdigit(tmp)) ungetc(tmp, stdin);

  while( scanf("%d", &secondArray[j]) == 1 && j < sizeof(secondArray) ) { 
    ++j; 
  }

  l1 = i; // preserve how many ints were read
  l2 = j;

/* Print this. */
  for(i = 0; i < l1; ++i)
  {
    printf("%d ", firstArray[i]);
  }
  putchar('\n');

  for(j=0; j < l2; ++j)
  {
    printf("%d ", secondArray[j]);
  }

  return 0;
}

编辑可能更适合您需要的解决方案是将行(每次一个)读入缓冲区并 sscanf 缓冲区。

于 2012-04-15T10:10:31.937 回答