【问题标题】:reading numbers from line in a file in C++从 C++ 文件中的行中读取数字
【发布时间】:2021-05-16 15:01:59
【问题描述】:

我有这个函数 process_input,它基本上获取文件的一行并打印该行的数字,如果它有 2 个数字,它会打印这些数字,否则它会打印 3 个数字。

我的问题是,由于某种原因,它使用 -1 标记重复打印行,我明白了原因。我的逻辑中是否有任何错误或我缺少的东西,有没有更有效的方法来做到这一点?我真正想要的是从文件中获取数字。

文件:

4 4
6 4
5 10
10 3
4 8
1 2 5
2 3 6
2 4 2
3 4 1

我的输出:

4 4 - tokens: 2
6 4 0 - tokens: 2
5 10 0 - tokens: 2
10 3 0 - tokens: 2
4 8 0 - tokens: 2
1 2 5 - tokens: 3
1 2 5 - tokens: -1
2 3 6 - tokens: 3
2 3 6 - tokens: -1
2 4 2 - tokens: 3
2 4 2 - tokens: -1
3 4 1 - tokens: 3
3 4 1 - tokens: -1
3 4 1 - tokens: -1

正确的输出:

4 4 - tokens: 2
6 4 0 - tokens: 2
5 10 0 - tokens: 2
10 3 0 - tokens: 2
4 8 0 - tokens: 2
1 2 5 - tokens: 3
2 3 6 - tokens: 3
2 4 2 - tokens: 3
3 4 1 - tokens: 3

程序:

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <stack>

using namespace std;

void process_input(int** &graph, int &V, int &E)
{
    int n,k;
    char line[6];

    fgets(line,6,stdin);
    int tokens = sscanf(line, "%d %d", &n, &k);
    printf("%d %d - tokens: %d\n",n,k,tokens);

    int x,y,w = 0;
    while (fgets(line,6,stdin) != NULL)
    {
        tokens = sscanf(line, "%d %d %d", &x,&y,&w);
        printf("%d %d %d - tokens: %d\n",x,y,w,tokens);
    }
}

int main(int argc, char **argv)
{
    int V, E;
    int **graph;
    process_input(graph,V,E);
    exit(0);
}

【问题讨论】:

  • C 风格的字符串是以 null 结尾的,这意味着 char line[6]; 可以在 null 终止符之前存储五个有意义的字符。 fgets(s, size, stream)stream 中读取最多比size 少一个字符,这包括换行符(如果有)。所以包含1 2 5 的行被读取到5 并且没有读取换行符,因为没有地方存储它。对fgets 的下一次调用只读取换行符而不读取数字。您可能希望稍微增加6。不如改用,嗯,我不知道,1024
  • 另一方面,您可能希望使用 C++ 工具,例如 std::stringiostreams,而不是低级 C 包,而不必担心这些微小的细节。
  • 谢谢,我不敢相信我犯了这样一个错误,我选择了 6,因为我认为它足够小,可以容纳该文件的任何一行。顺便说一句,由于数据结构的原因,我只使用 c++,因为我真的不知道如何用 c++ 编程。

标签: c++ file


【解决方案1】:

问题是,一旦您在循环中输入数字,您就不会清除您的stdin 缓冲区。你在这里混合了CC++

在 C++ 中你会这样做:

while (fgets(line,6,stdin) != NULL)
{   
    tokens = sscanf(line, "%d %d %d", &x,&y,&w);
    printf("%d %d %d - tokens: %d\n",x,y,w,tokens);
    std::cin.ignore();
    std::cin.clear();
}

您必须包含iostream。使用C 的方式并不完美,但是here is SO post about it

在仔细检查时使用十六进制输出(这是针对C,您正在覆盖\n。这使得scanf 函数失败,这就是您得到-1 的原因,以及它为什么不自行清除缓冲区。

int n,k;
char line[7];

fgets(line,7,stdin);
int tokens = sscanf(line, "%d %d", &n, &k);
printf("%d %d - tokens: %d\n",n,k,tokens);

int x,y,w = 0;                                                                                                                                            
while (fgets(line,7,stdin) != NULL)
{
    tokens = sscanf(line, "%d %d %d\n", &x,&y,&w);
    printf("%d %d %d - tokens: %d\n",x,y,w,tokens);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 2021-12-19
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    相关资源
    最近更新 更多