使用 strcat 连接文件中的行

Using strcat to concatenate lines from a file

我正在尝试读取一个文件和下一行的一行,看看它是否以 space 开头,例如:

First line
 second line 
Third line
 fourth line

当我读取文件时,我想检查下一行是否有 space,如果有,我想对这两行进行 strcat(在本例中为第一行和第二行)。

第一个例子:

1.) 阅读第一行,提前阅读第二行,看到它们是一个 space,并且 strcat 两个字符串,使 "First linesecond line"(重复后面的任何其他行这个模式)。

这是我的做法:

int main(void) {
    FILE * file = fopen("file.txt","r");

    if(file==NULL) { return 0; }

    char * fileBuffer = malloc(sizeof(char)*100);
    char * temp = malloc(sizeof(char)*100);

    while(fgets(fileBuffer,100,file) != NULL) {
        if(isspace(fileBuffer[0])) {

            strcpy(temp,fileBuffer);

            //store line that has a space in static temporary variable
        }
        else {
            if(strcmp(temp,"") != 0) { //if temp is not empty
                strcat(fileBuffer,temp);
            }
        }
    }
    free(fileBuffer);
    free(temp);

    return 0;
}

但是这不起作用。发生的事情是当 fgets 被执行时,它读取第一行,它看到没有白色 space,然后转到下一行,看到有白色 space,存储它,但现在是 fileBuffer不再包含第一行,但包含第二行。

所以当我下次 strcat 时,我没有得到 "First linesecond line" 的正确结果。

相反,我得到的是第三行与第二行混合的结果,这不是我想要的。

我不太确定如何修正我的逻辑,有什么想法吗?

您还有几个其他的注意事项需要处理。首先,您需要删除 fgets 读取中包含的尾随 '\n'。为此,您需要读取行的长度。然后,您可以通过用 nul-terminating 字符覆盖它来删除试用 '\n'。例如:

while (fgets (buf1, MAXC, fp)) {
    size_t len1 = strlen (buf1);  /* get length */
    if (len1 && buf1[len1-1] == '\n') buf1[--len1] = 0; /* remove \n */

另一个考虑因素是如何管理用于组合线路的内存的分配和释放。由于您正在从相对固定长度的字符串中读取最后一行的第一部分,然后是第二部分,因此使用 2 更有意义静态缓冲区,一个用于读取行,一个用于保存第一个的副本。您可以分配最终结果。例如

enum { MAXC = 100 };  /* constant for max characters */
...
int main (int argc, char **argv) {

    char buf1[MAXC] = {0};
    char buf2[MAXC] = {0};
    char *both = NULL;

一旦您准备好将生产线的两个部分组合起来,您就可以准确分配所需的 space,例如

        if (*buf1 == ' ' && *buf2) {
            both = malloc (len1 + strlen (buf2) + 1);
            strcpy (both, buf2);
            strcat (both, buf1);
            ...

不要忘记在每次分配后free both。将各个部分放在一起,并确定比较的逻辑,您最终可能会得到如下解决方案:

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

enum { MAXC = 100 };

int main (int argc, char **argv) {

    char buf1[MAXC] = {0};
    char buf2[MAXC] = {0};
    char *both = NULL;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    if (!fp) {
        fprintf (stderr, "error: file open failed '%s'.\n,", argv[1]);
        return 1;
    }

    while (fgets (buf1, MAXC, fp)) {
        size_t len1 = strlen (buf1);
        if (len1 && buf1[len1-1] == '\n') buf1[--len1] = 0;
        if (*buf1 == ' ' && *buf2) {
            both = malloc (len1 + strlen (buf2) + 1);
            strcpy (both, buf2);
            strcat (both, buf1);
            printf ("'%s'\n", both);
            free (both);
            *buf2 = 0;
        }
        else
            strcpy (buf2, buf1);
    }
    if (fp != stdin) fclose (fp);

    return 0;
}

输出

$ ./bin/cpcat ../dat/catfile.txt
'First line second line'
'Third line fourth line'

仔细阅读,如果您有任何问题,请告诉我。

像这样修正你的逻辑:

#define LINE_SIZE 100

int main(void) {
    FILE * file = fopen("file.txt","r");

    if(file==NULL) { perror("fopen"); return -1; }

    char * fileBuffer = malloc(LINE_SIZE);
    char * temp = malloc(LINE_SIZE * 2);//Binding of the string is only once

    while(fgets(fileBuffer, LINE_SIZE, file) != NULL) {
        if(isspace(fileBuffer[0])) {
            temp[strcspn(temp, "\n")] = 0;//remove newline
            strcat(temp, &fileBuffer[1]);
            printf("%s", temp);
        }
        else {
            strcpy(temp, fileBuffer);
        }
    }
    fclose(file);
    free(fileBuffer);
    free(temp);

    return 0;
}

确实是一种快速而肮脏的方式

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

int main(void) {

    FILE * file = fopen("file.txt", "r");

    if (file == NULL) { return 0; }

    char fileBuffer[100];
    char temp[100];
    int first = 1;

    while (fgets(fileBuffer, 100, file) != NULL) {
        if (isspace(fileBuffer[0])) {

            strcat(temp, fileBuffer);
            //store line that has a space in static temporary variable
        }
        else {
            if (first == 1){
                strncpy(temp, fileBuffer, sizeof(temp));

                // Remove the end line
                temp[strlen(temp) - 1] = 0;
                strcat(temp, " ");
                first = 0;
            }
            else{
                if (strcmp(temp, "") != 0) { //if temp is not empty
                    strcat(temp, fileBuffer);

                    // Remove the end line
                    temp[strlen(temp) - 1] = 0;
                    strcat(temp, " ");
                }

            }

        }
    }
    printf("%s", temp);
    free(fileBuffer);
    free(temp);

    return 0;
}

输出: