Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 处理文件时的混乱_C_String_File_Format - Fatal编程技术网

C 处理文件时的混乱

C 处理文件时的混乱,c,string,file,format,C,String,File,Format,我正在编写一个程序,它从一个文件中提取一个字符串,从另一个文件中提取一个字符串,然后将它们分别写入第三个文件的列中。我真的有两个问题,如果我使用fgets从文件中获取字符串,它会停在行的末尾。它会自动知道下一个字符串从下一行开始。另外,如何格式化输入以生成两列。例如 第一个字符串是第一个文件中的“John”。 第二个字符串是第二个文件中的“applesed” 第三个文件中会有“John 第三个文件的第二行将显示“Benny\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

我正在编写一个程序,它从一个文件中提取一个字符串,从另一个文件中提取一个字符串,然后将它们分别写入第三个文件的列中。我真的有两个问题,如果我使用fgets从文件中获取字符串,它会停在行的末尾。它会自动知道下一个字符串从下一行开始。另外,如何格式化输入以生成两列。例如

第一个字符串是第一个文件中的“John”。 第二个字符串是第二个文件中的“applesed”

第三个文件中会有“John 第三个文件的第二行将显示“Benny\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


只是格式化列。

您想要下划线,还是空格就足够了?使用空格更简单。您可以阅读的规格 查看格式字符串的详细功能

while (fgets(buffer1, sizeof(buffer1), fp1) != 0 &&
       fgets(buffer2, sizeof(buffer2), fp2) != 0)
{
    buffer1[strcspn(buffer1, "\n")] = '\0';
    buffer2[strcspn(buffer2, "\n")] = '\0';
    fprintf(fp3, "%-25s   %s\n", buffer1, buffer2);
}
这将从前两个文件中的每一个文件中读取一行,从缓冲区中删除换行符,然后格式化它们,第一列左对齐,宽度为25,第二列在3个空格后打印

如果必须使用下划线而不是空格,则需要如下内容:

char uscore[256];
memset(uscore, '_', sizeof(uscore)-1);
uscore[sizeof(uscore)-1] = '\0';

while (fgets(buffer1, sizeof(buffer1), fp1) != 0 &&
       fgets(buffer2, sizeof(buffer2), fp2) != 0)
{
    buffer1[strcspn(buffer1, "\n")] = '\0';
    buffer2[strcspn(buffer2, "\n")] = '\0';
    int len1 = max(0, 25 - strlen(buffer1));
    fprintf(fp3, "%s%*.*s%s\n", buffer1, len1, len1, uscore, buffer2);
}
将这两种技术放在一起,同时说明:

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

int main(int argc, char **argv)
{
    if (argc != 4)
    {
        fprintf(stderr, "Usage: %s infile-1 infile-2 outfile\n", argv[0]);
        return 1;
    }
    FILE *fp1 = fopen(argv[1], "r");
    FILE *fp2 = fopen(argv[2], "r");
    FILE *fp3 = fopen(argv[3], "w");
    if (fp1 == 0 || fp2 == 0 || fp3 == 0)
    {
        fprintf(stderr, "%s: failed to open one of the files %s, %s or %s\n",
                argv[0], argv[1], argv[2], argv[3]);
        return 1;
    }

    char uscore[256];
    memset(uscore, '_', sizeof(uscore)-1);
    uscore[sizeof(uscore)-1] = '\0';
    char buffer1[1024];
    char buffer2[1024];

    while (fgets(buffer1, sizeof(buffer1), fp1) != 0 &&
           fgets(buffer2, sizeof(buffer2), fp2) != 0)
    {
        buffer1[strcspn(buffer1, "\n")] = '\0';
        buffer2[strcspn(buffer2, "\n")] = '\0';
        fprintf(fp3, "%-25s   %s\n", buffer1, buffer2);

        int len1 = strlen(buffer1);
        if (len1 < 28)
            len1 = 28 - len1;
        else
            len1 = 0;
        fprintf(fp3, "%s%*.*s%s\n", buffer1, len1, len1, uscore, buffer2);
    }
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);
    return 0;
}
示例输入文件
数据.2

干旱 迫害 初步的 充足的 懦弱的 文件中有相当长的单词。2太长了 示例输出:

加州干旱 加利福尼亚州干旱 秘密迫害 深奥的迫害 不匹配初步 不匹配-初步 出人意料的足够 意外的uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 无足轻重 非顺序性 文件1中的超长单词列表相当于文件2中的较长单词 文件中的超长单词列表1文件中的其他超长单词。2 您可以根据所需格式的更精确定义进行无休止的调整。除此之外,您可以确保“必须有下划线”示例中的第一个和第二个单词之间至少有3个下划线。您可以限制打印字符串的长度


代码应该检查它是否在前1023字节内得到一个换行符;不需要。

您想要下划线,还是空格就足够了?使用空格更简单。您可以阅读的规格 查看格式字符串的详细功能

while (fgets(buffer1, sizeof(buffer1), fp1) != 0 &&
       fgets(buffer2, sizeof(buffer2), fp2) != 0)
{
    buffer1[strcspn(buffer1, "\n")] = '\0';
    buffer2[strcspn(buffer2, "\n")] = '\0';
    fprintf(fp3, "%-25s   %s\n", buffer1, buffer2);
}
这将从前两个文件中的每一个文件中读取一行,从缓冲区中删除换行符,然后格式化它们,第一列左对齐,宽度为25,第二列在3个空格后打印

如果必须使用下划线而不是空格,则需要如下内容:

char uscore[256];
memset(uscore, '_', sizeof(uscore)-1);
uscore[sizeof(uscore)-1] = '\0';

while (fgets(buffer1, sizeof(buffer1), fp1) != 0 &&
       fgets(buffer2, sizeof(buffer2), fp2) != 0)
{
    buffer1[strcspn(buffer1, "\n")] = '\0';
    buffer2[strcspn(buffer2, "\n")] = '\0';
    int len1 = max(0, 25 - strlen(buffer1));
    fprintf(fp3, "%s%*.*s%s\n", buffer1, len1, len1, uscore, buffer2);
}
将这两种技术放在一起,同时说明:

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

int main(int argc, char **argv)
{
    if (argc != 4)
    {
        fprintf(stderr, "Usage: %s infile-1 infile-2 outfile\n", argv[0]);
        return 1;
    }
    FILE *fp1 = fopen(argv[1], "r");
    FILE *fp2 = fopen(argv[2], "r");
    FILE *fp3 = fopen(argv[3], "w");
    if (fp1 == 0 || fp2 == 0 || fp3 == 0)
    {
        fprintf(stderr, "%s: failed to open one of the files %s, %s or %s\n",
                argv[0], argv[1], argv[2], argv[3]);
        return 1;
    }

    char uscore[256];
    memset(uscore, '_', sizeof(uscore)-1);
    uscore[sizeof(uscore)-1] = '\0';
    char buffer1[1024];
    char buffer2[1024];

    while (fgets(buffer1, sizeof(buffer1), fp1) != 0 &&
           fgets(buffer2, sizeof(buffer2), fp2) != 0)
    {
        buffer1[strcspn(buffer1, "\n")] = '\0';
        buffer2[strcspn(buffer2, "\n")] = '\0';
        fprintf(fp3, "%-25s   %s\n", buffer1, buffer2);

        int len1 = strlen(buffer1);
        if (len1 < 28)
            len1 = 28 - len1;
        else
            len1 = 0;
        fprintf(fp3, "%s%*.*s%s\n", buffer1, len1, len1, uscore, buffer2);
    }
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);
    return 0;
}
示例输入文件
数据.2

干旱 迫害 初步的 充足的 懦弱的 文件中有相当长的单词。2太长了 示例输出:

加州干旱 加利福尼亚州干旱 秘密迫害 深奥的迫害 不匹配初步 不匹配-初步 出人意料的足够 意外的uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 无足轻重 非顺序性 文件1中的超长单词列表相当于文件2中的较长单词 文件中的超长单词列表1文件中的其他超长单词。2 您可以根据所需格式的更精确定义进行无休止的调整。除此之外,您可以确保“必须有下划线”示例中的第一个和第二个单词之间至少有3个下划线。您可以限制打印字符串的长度

代码应该检查它是否在前1023字节内得到一个换行符;没有

如果我使用fgets从文件中获取字符串,它将停止在行的末尾。它会自动知道下一个字符串从下一行开始

如果该行可以完全存储在缓冲区中,则是,它将(详见下文)

但是,从文件中读取的数据中并没有类似于行的内容。它更像是一个连续的字节流。如果编辑器中有一个类似以下内容的文件:

a
b
c
fgets
看到的数据更像这个字节流:

a\nb\nc\n
fgets
的第一次调用将读取
a
\n
并将剩余的输入保留为

b\nc\n
fgets
的下一次调用将读取
b
\n
,因此它的工作原理就像是从“下一行”开始,但实际上只是从上次调用停止的地方继续

还要注意,如果行比缓冲区长,会发生什么情况。如果文件是

abcd
efgh
你呢

fgets(buffer, 3, f)
然后,对
fgets
的第一次调用将给出
ab\0
,下一次调用将继续读取
cd\0

换句话说,如果行太长,无法完全存储在缓冲区中,
fgets
将从“下一行”继续。如果总是希望从下一行继续,则必须添加代码以从文件中读取,直到读取
\n

另外,如何格式化输入以生成两列

好吧,你的问题没有包括足够的细节来给出准确的代码,例如,列之间的间距应该是多少,如果输入大于间距,该怎么办,等等

在任何情况下,请看(乔纳森·莱弗勒的)这篇文章,它给了你一些很好的提示

如果我使用fgets从文件中获取字符串,它将停止在行的末尾。它会自动知道如何启动吗