【问题标题】:c/c++ scanf/cin reads int from multiple linesc/c++ scanf/cin 从多行读取int
【发布时间】:2013-08-04 21:01:48
【问题描述】:

我正在用 c/c++ 做一些基本的输入解析。

格式:值的数量,后跟空格分隔的值:

3
5 2 4

这里的问题是第一行后面没有空格。这会导致 cin 和 scanf 将 35 读入第一个变量,而不是 3。

int num;

scanf("%d", &num);

int array[num];
for (int i = 1; i <= num; i++) {
    scanf("%d", &array[i]);
}

如何让 cin 或 scanf 在换行符处停止解析?

编辑: 即使稍后在读取之前写入变量,也不初始化变量是不是很糟糕? (int num)

如果我输入输入,它会起作用,但如果我粘贴它就不会。有什么线索吗?

【问题讨论】:

  • 它们都停在第一个空格处。新行是一个空白,因此它们都停在那里。
  • 发布一个小而完整的程序来显示问题。 scanf 和流提取器忽略行尾。
  • 真正的问题是,您使用的是 C 还是 C++?
  • @FilipHaglund:一些 C 代码应该在 C++ 中工作,但不是所有 C 代码。例如,您发布的代码是有效的 C99 代码,但不是有效的 C++ 代码。
  • @PeteBecker 问题是关于scanf std::cin例子是关于scanf.

标签: c++ c


【解决方案1】:

std::cin 将换行符解释为空格,因此您正在使用的文件可能包含换行符以外的内容。您还使用非标准扩展来声明数组。这是不可移植的,也不保证所有编译器都支持。我建议你改用std::vector

您的for 循环也不正确。数组使用从零开始的索引来访问它们的元素。因此,您最终会越界访问数组,这是未定义的行为。这意味着您的程序可能会崩溃,它可能会覆盖其他变量,或者您可能根本没有注意到任何症状。如果它覆盖其他变量,这也可能导致您遇到的症状。

下面的示例使用 C++ 输入流而不是 scanf 来提供更好的错误检查。

#include <istream>
#include <vector>

std::vector<int> load(std::istream& in)
{
    std::size_t count;
    std::vector<int> data;

    // If the user does not enter a number "in >> count" will fail.
    if (in >> count)
    {
        int value;
        while (count-- && in >> value)
            data.push_back(value);
    }

    return data;
}


#include <iostream>

int main()
{
    auto data = load(std::cin);
    for (auto i : data)
        std::cout << i << std::endl;
}

您可以通过使用std::stringstream 作为输入来测试它而无需从文件中读取。

#include <iostream>
#include <sstream>
int main()
{
    std::stringstream text("3\n5 2 4");
    auto data = load(text);

    for (auto i : data)
        std::cout << i << std::endl;
}

【讨论】:

  • count &gt; 0不需要检查;此外,count-- 是一个丑陋的解决方法,因为它懒得声明一个新变量(仍然为你的答案 +1)
  • +1 是唯一基于 C++ 而不是基于 C 的答案。
  • @anatolyg 糟糕,感谢您指出这一点。 count &gt; 0 改成size_t 后忘记删除了。
【解决方案2】:

在 for 循环中,您从位置 1 而不是 0 开始数组。这会导致超出范围,因为您想写入数组的元素 2。如果您分配一个包含 2 个元素的数组,则有效元素将是 0 和 1。此代码有效:

int num;

scanf("%d", &num);

int array[num];

for (int i = 0; i < num; i++)
{
    scanf( "%d", &array[i] );
}

【讨论】:

  • 此代码可能适用于 C++ 编译器。它不适用于 Microsoft 的 C 编译器。
【解决方案3】:

0 开始array,因为数组索引从0 开始 - 比如:

for (int i = 0; i < num; i++) 

您从 1 开始第一个元素,这使得它未定义。此外,你应该制作动态数组。

【讨论】:

  • 你应该有i &lt; num,否则最后一个元素可能超出范围。
  • i == num 数组外边。
  • @ShumailMohy-ud-Din :) 为什么是我?
【解决方案4】:

我喜欢 Lidong Guo 的代码,并对其进行了修改以使用 Microsoft 的 C 编译器运行。 唯一的变化是将所有数据定义移到任何可执行代码之前,另外我在打印的数字之间添加了一个空格。

  #include <stdio.h>
  #include <stdlib.h>
  main()
  {
       int num;

       int *array; //[num];
       int i;

       scanf("%d\n", &num);//here deal with the newlinw
       array= malloc(sizeof(int) *num);//[num];

       for (i = 0; i < num; i++)
       {//the loop .start 0 end num -1
          scanf("%d", &array[i]);
       }

       for (i = 0; i < num; i++)
       {
          printf("%d ", array[i]);
       }

       free(array);
 }

【讨论】:

    【解决方案5】:

    [编辑:答案特定于 C++,因为问题也有 C++ 标签]

    嗯,第一件事。

    你的数组定义是错误的。

    int array[num];    // Super wrong way
    

    在定义数组时,您不应该将变量作为索引传递,这是不允许的。否则会引发“鼻恶魔”。

    int * array = new int[num]    //correct way
    

    代码现在可能工作正常,但您给出的数组定义属于 UB 类别。

    【讨论】:

    • 这取决于语言。在 C 中允许使用可变长度数组,但在 C++ 中(目前)还不允许(尽管 g++ 中有一个 GNU 扩展允许它们)。
    • @Cornstalks;代码是用 C 编写的。
    • OP提到cin,所以他们可能使用C++
    • 嘿,我说的是 c++ =.= 。这家伙也把它标记在 C++ 下
    • @Dr.Xperience;然后让你的答案具体到 C++。
    【解决方案6】:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int num;
        scanf("%d", &num);
    
        int *array= malloc(sizeof(int) *num);    // num is known at runtime
        int i;
        for (i = 0; i < num; i++) {    //starts at 0, ends at num - 1 
            scanf("%d", &array[i]);
        }
        for (i = 0;i< num; i++) {
            printf("%d", array[i]);
        }
        free(array);
    }
    

    【讨论】:

    • 此代码在使用 Microsoft 的 C 编译器编译时不起作用。
    【解决方案7】:

    改变

    扫一扫

    声明到

    scanf("%d", &array[i]);

    数组索引也是从 0 开始到 num-1 结束

    【讨论】:

      【解决方案8】:

      0 开始循环并在num-1 结束循环,即

      for (int i = 0; i < num - 1; i++) 
          scanf("%d", &array[i]);   
      

      粘贴输入不起作用的原因是它在两行之间不包含换行符

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 2014-01-28
      • 1970-01-01
      相关资源
      最近更新 更多