首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确获取一行并使用C进行解析

如何正确获取一行并使用C进行解析
EN

Stack Overflow用户
提问于 2019-03-25 16:23:48
回答 2查看 330关注 0票数 0

我正在编写一个C程序,它将打开一个文件,写入它,然后读取所写的内容。我可以打开、写入和关闭文件,但是我不能正确地读取和解析这些行。

我读过很多其他的博客和网站,但是没有一个能完全解决我想要做的事情。我试过调整他们的一般解决方案,但我从来没有得到我想要的行为。我已经使用fget()、get()、strtok()、scanf()和fscanf()运行了这段代码。我使用了strtok_r(),因为它被推荐为最佳实践。我使用get()和scanf()作为实验来查看它们的输出是什么,而不是fget()和fscanf()。

我想做的是:

  1. get第一行//第一行是由空格分隔的字符串ints "1 2 3 4 5“。
  2. 解析这一行,将每个字符数转换为整数。
  3. 将其存储到数组中。
  4. 取下一行并重复,直到EOF

谁能告诉我我错过了什么,哪些功能会被认为是最佳实践?

谢谢

我的代码:

代码语言:javascript
复制
#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(){
  FILE * file;

  // read data from customer.txt
  char lines[30];
  file = fopen("data.txt", "r"); 
  // data.txt currently holds five lines
  // 1 1 1 1 1 
  // 2 2 2 2 2
  // 3 3 3 3 3
  // 4 4 4 4 4 
  // 5 5 5 5 5

  char *number;
  char *next = lines;


  int s = 0;
  int t = 0;
  int num;
  int prams[30][30];

  while(fgets(lines, 30, file)){
        char *from = next;

    while((number = strtok_r(from, " ", &next)) != NULL){
        int i = atoi(number);
        prams[t][s] = i;
        printf("this is prams[%d][%d]: %d\n", t, s, prams[t][s]);

        s++;
        from = NULL;               
    }

    t++;
  }

  fclose(file);
}// main

预期产出:

这是婴儿车:1 ..。 这是prams4: 5

实际产出:

这是婴儿车:1 这是婴儿车:1 这是婴儿车:1 这是婴儿车:1 这是婴儿车:1 程序结束

EN

回答 2

Stack Overflow用户

发布于 2019-03-25 16:34:20

直接的主要问题是,您一直告诉strtok_r()从字符串的开头开始,所以它继续返回相同的值。您需要将第一个参数设置为strtok_r()为NULL,这样它就会继续运行:

代码语言:javascript
复制
char *from = next;
while ((number = strtok_r(from, " ", &next)) != NULL)
{
    int i = atoi(number);
    prams[t][s] = i;
    printf("this is prams[%d][%d]: %d\n", t, s, prams[t][s]);
    s++;
    from = NULL;               
}

有些人会支持strtol()而不是atoi();他们有一些正义,但可能还不够重要。

还请参阅 in loops?,以了解如何使用sscanf()解析行。

使用:

代码语言:javascript
复制
while (fgets(lines, 30, file))

对于外部循环控制;除了(可能)在循环结束后的feof()之外,用于区分EOF和I/O错误。(几年前,我查看了我的数百个C源文件,发现eof()的使用不到六次,都是在错误检查代码中,在循环控件中则没有。你真的不需要经常使用它。)

票数 1
EN

Stack Overflow用户

发布于 2019-03-25 17:21:57

如果你想解析空格分隔的文本,那么扫描和朋友是你最好的选择。但是,如果您想要特殊地对待换行符而不是将其作为空白,那么您需要fgets+sscanf循环:

代码语言:javascript
复制
#define ROWS 30
#define COLS 30
#define MAXLINE 512
int prams[ROWS][COLS];
int row, col, len;
char buffer[MAXLINE], *p;

row = 0;
while (row < ROWS && fgets(buffer, MAXLINE, stdin)) {
    col = 0;
    p = buffer;
    while (col < COLS && sscanf(p, "%d %n", &prams[row][col], &len) > 0) {
        p += len;
        ++col; }
    if (*p) {
        /* extra stuff on the end of the line -- error? */ }
    ++row; }

注还检查边界,以确保没有超出固定大小的数组边界.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55342279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档