逐行读取直到找到整数C.

时间:2015-05-14 09:06:33

标签: c string file file-io int

尝试创建一个接收文本文件并逐行读取的程序。然后它找到每行上的两个整数并将它们加在一起。然后它将原始字符串和total的新行输出到新的文本文件。我需要帮助添加两个整数,从每一行获取它们,然后将新行放到文本文件中。

输入文本文件

good morning hello 34 127
ann 20 45
10 11
fun program and you find the same 90 120
news paper said that 56 11
how do you like 20 5
line number 90 34

首先输出如下:然后继续

good morning hello 161

代码:

int processTextFile(char * inputFileName, char * outputFileName)
{
   FILE *fp = fopen(inputFileName, "r");//open file to to read
   char buff[1024];
   char *p, *p1;
   int num;
   while (fgets(buff, 1024, fp)!=NULL)
   {
      printf("%s\n", buff);
      while(scanf(buff, "%*[^0-9]%d", &num)== 1)
         printf("%d\n", num);
      //fscanf(fp, "%s", buff);
   }

   return 0;
}

EDIT !!!! ::

所以现在我已经能够做到这一点。我如何根据产生的数字对其进行排序?例如:

Time is money 52
here I am 3
21

将按照

的顺序输出到新的文本文件
here I am 3
21
Time is money 52

3 个答案:

答案 0 :(得分:2)

我使用man 7 signal的版本应该与 stdin 一起用于输入,而 stdout 用于输出。 (所以你可以做executable <textfile >newtextfile

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char line[1000];
    while (fgets(line, sizeof line, stdin)) {
        char *ptr;
        size_t x = strcspn(line, "0123456789");
        if (line[x]) {
            errno = 0;
            int n1 = strtol(line + x, &ptr, 10);
            if (*ptr && !errno) {
                errno = 0;
                int n2 = strtol(ptr, &ptr, 10);
                if (*ptr && !errno) {
                    int n3 = n1 + n2;
                    printf("%.*s%d\n", (int)x, line, n3);
                } else {
                    printf("%s", line); // line includes ENTER
                }
            } else {
                printf("%s", line); // line includes ENTER
            }
        } else {
            printf("%s", line); // line includes ENTER
        }
    }
    return 0;
}

没有错误检查的相同版本

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char line[1000];
    while (fgets(line, sizeof line, stdin)) {
        char *ptr;
        size_t x = strcspn(line, "0123456789");
        int n1 = strtol(line + x, &ptr, 10);
        int n2 = strtol(ptr, &ptr, 10);
        int n3 = n1 + n2;
        printf("%.*s%d\n", (int)x, line, n3);
    }
    return 0;
}

答案 1 :(得分:0)

方法应该是:

  1. 打开两个文件,一个用于输入,一个用于输出。
  2. 使用sscanf()读取输入缓冲区。
  3. 扫描前导字符串,然后两个数字。
  4. 如果之前的sscanf()失败,则只检查两个号码。
  5. 如果上述扫描中的任何一个成功,则将总和打印到输出文件。
  6. 示例代码应该看起来像

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void)
    {
    
            FILE *fpin = fopen("ipfile", "r");//open file to to read
            if (!fpin)
            {
                    printf("Error in ipfile opening\n");
                    exit (-1);
            }
            FILE *fpout = fopen("opfile", "w");//open file to to write
            if (!fpout)
            {
                    printf("Error in opfile opening\n");
                    exit (-1);
            }
            char buff[1024] = {0};
            char str[1024] = {0};
            int num1 =0, num2= 0;
            while (fgets(buff, 1024, fpin)!=NULL)
            {
                    memset(str, 0, sizeof(str));
                    //printf("%s\n", buff);
                    if(sscanf(buff, "%[^0-9]%d %d", str, &num1, &num2)== 3)
                        fprintf(fpout, "%s %d\n", str, (num1+num2));
                    else if (sscanf(buff, "%d %d", &num1, &num2)== 2)
                        fprintf(fpout, "%d\n", (num1+num2));
            }
    
            return 0;
    }
    

    注意:

    上述过程是一种解决方法。如果文件中的数据模式发生变化,则需要进行大量更改才能维护这样的代码。而不是usinf sscnaf(),为了更好和更好的方法,你应该

    1. 从文件中读取行
    2. 开始标记输入缓冲区(strtok())并检查int为标记(strtol())。
    3. 单独保存退回的令牌和int
    4. 一旦strtok()返回NULL,就会打印字符串标记以及整数到o / p文件的内容。

答案 2 :(得分:0)

我打算不要完全更改你的代码,所以我只是添加了一些代码片段以供改进。

int processTextFile(char *inputFileName, char *outputFileName) {

     FILE *fp = fopen(inputFileName, "r");
     FILE *out = fopen(outputFileName, "w");
     char line[1024];

     if (!fp) {
          perror(inputFileName);
          return;
     }

     while (fgets(line, sizeof(line), fp) != NULL) {
          int num1 = 0, num2 = 0;
          char textPart[1024] = "";
          if ( !sscanf(line, "%[a-zA-Z' ']%d%d", textPart, &num1, &num2) {
               sscanf(line, "%d%d", &num1, &num2);
          }
          fprintf(out, "%s %d\n", textPart, num1 + num2);
     }
     fclose(fp);
     fclose(out);
}

<强>解释

我扫描了文本文件,提取了文本部分和两个ints。由于我注意到ints位于每行的末尾,因此我只使用了sscanf()

sscanf(line, "%[a-zA-Z' ']%d%d", textPart, &num1, &num2);

此处,"%[a-zA-Z' ']%d%d"格式说明符表示只获取字母和空格。

由于它只会输入字母和空格,因此输入文件中的行"10 11"不会被放到num1num2。因为代码首先检查包含字母和空格的字符串。由于10和11不属于限定类型,因此只是跳过该行。

这就是我添加if-else语句的原因,该语句检查sscanf是否将任何内容写入内存。如果sscanf返回0,则表示不存在任何文本部分。只是数字。所以程序会扫描两位数字。

if ( !sscanf(line, "%[a-zA-Z' ']%d%d", textPart, &num1, &num2) ) {
    sscanf(line, "%d%d", &num1, &num2);
}

我还添加了输入文件的文件检查。它检查文件是否不存在或文件流无法打开。

if (!fp) {
      perror(inputFileName);
      return;
}

以下是执行后输出文件的内容:

good morning hello  161
ann  65
21
fun program and you find the same  210
news paper said that  67
how do you like  25
line number  124