简体   繁体   English

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

[英]Read Line By Line Until Integer is Found C

Trying to create a program that takes in a text file and reads it line by line. 试图创建一个接收文本文件并逐行读取的程序。 It then finds the two integers that are on each line and adds them together. 然后,找到每行上的两个整数并将它们加在一起。 It then outputs the new line with the original string and total to a new text file. 然后,它将带有原始字符串的新行输出并总计到一个新的文本文件。 I need help adding the two integers, getting them from each line, and then putting the new line to a text file. 我需要帮助添加两个整数,从每一行中获取它们,然后将新行放入文本文件中。

input text file 输入文字档

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

Outputs first like would look like: and then continue on 首先的输出看起来像:然后继续

good morning hello 161

Code: 码:

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!!!!:: 编辑!!!!::

So now that I've been able to accomplish this. 现在,我已经能够完成此任务。 How would I sort it by the number produced? 如何按产生的数字对其进行排序? for example: 例如:

Time is money 52
here I am 3
21

Would output to a new text file in order like 将按以下顺序输出到新的文本文件

here I am 3
21
Time is money 52

My version using strcspn() is supposed to work with stdin for input and stdout for output. 我的使用strcspn()版本应该与stdin一起使用 ,而stdout则用于输出。 (so you can do executable <textfile >newtextfile ) (所以您可以执行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;
}

The same version without the error checking 没有错误检查的相同版本

#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;
}

The approach should be: 该方法应为:

  1. open two files, one for input, one for output. 打开两个文件,一个用于输入,一个用于输出。
  2. use sscanf() to read the input buffer. 使用sscanf()读取输入缓冲区。
  3. scan the leading string, and then two number. 扫描前导字符串,然后扫描两个数字。
  4. if previous sscanf() fails, only check for two number. 如果以前的sscanf()失败,则仅检查两个数字。
  5. if either of the above scanning is success, print the sum to the output file. 如果以上任一扫描均成功,则将总和打印到输出文件中。

A sample code, should look like 示例代码应该看起来像

#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;
}

Note: 注意:

The above procedure, is a kind of workaround . 上面的过程,是一种解决方法 If the data pattern in the file changes, lot of changes will be required to maintain a code like that. 如果文件中的数据模式发生更改,则需要大量更改来维护这样的代码。 Instead of usinf sscnaf() , for a better and roubust approach, you should 代替usinf sscnaf() ,以获得更好,更强大的方法,您应该

  1. read the line from file 从文件中读取行
  2. start tokenizing the input buffer ( strtok() ) and check for int s as tokens ( strtol() ). 开始标记化输入缓冲区( strtok() )并检查int作为标记( strtol() )。
  3. save the returned tokens and int s seperately. 保存返回的令牌,并分别保存int
  4. once the strtok() returns NULL, you print the string tokens and the sum of the ints to the o/p file. 一旦strtok()返回NULL,就可以将字符串标记和整数之和打印到o / p文件中。

I intend not to change your code completely, so I just added some snippets for improvement. 我不打算完全更改您的代码,因此我只添加了一些代码片段以进行改进。

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);
}

Explanation: 说明:

I scanned the text file, extracted the text part and the two ints . 我扫描了文本文件,提取了文本部分和两个ints Since I noticed that the ints are placed at the end of each line, I just used sscanf() for that matter. 由于我注意到ints位于每行的末尾,因此我只使用sscanf()

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

Here, "%[a-zA-Z' ']%d%d" format specifiers means to get only alphabets and spaces. 在这里, "%[a-zA-Z' ']%d%d"格式说明符意味着仅获取字母和空格。

Since it will only get letters and spaces, the line "10 11" in your input file won't be put to num1 and num2 . 由于只会得到字母和空格,因此输入文件中的行"10 11"将不会放在num1num2 Because the code inspects first for a string containing letters and spaces. 因为代码首先检查包含字母和空格的字符串。 Since 10 and 11 are not of the qualified types, then the line is just skipped. 由于10和11不是合格类型,因此仅跳过该行。

That's why I added an if-else statement, which checks if sscanf wrote anything to memory. 这就是为什么我添加了一条if-else语句,该语句检查sscanf是否向内存中写入了任何内容。 If sscanf returned 0, then it means that no text part is present. 如果sscanf返回0,则表示不存在任何文本部分。 Just digits. 只是数字。 So the program will scan the two digits. 因此,程序将扫描两位数。

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

I also added file checking for input file. 我还添加了检查输入文件的文件。 It checks if file doesn't exist or can't be opened by the filestream. 它检查文件是否不存在或文件流无法打开。

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

Here is the content of output file after execution: 这是执行后输出文件的内容:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM