我编写的程序从一个文件中获取一个字符串,从另一个文件中获取一个字符串,并将它们写入不同列中的第三个文件。我真的有两个问题,如果我使用fgets从文件中获取字符串,它会在行尾停止。是否会自动知道从下一行开始下一个字符串。另外,如何格式化输入以生成两列。一个例子是......
第一个字符串是" John"从第一个文件。 第二个字符串是" Appleseed"来自第二个文件。
第三个文件将在其中"约翰______________________ Appleseed" 第三个文件的第二行有" Benny __________________________ Backburner"
只是格式化列。
答案 0 :(得分:2)
你想要下划线,还是空间足够?空间更简单。您可以阅读printf()
的规范
查看格式字符串的详细信息。
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;
}
示例输入文件data.1
:
California
Esoteric
Mismatch
Unexpected
Non-sequitur
Extra-long word list from file 1
示例输入文件data.2
:
Drought
Persecution
Preliminary
Adequate
Pusillanimous
Rather long word from file.2 too
示例输出:
California Drought
California__________________Drought
Esoteric Persecution
Esoteric____________________Persecution
Mismatch Preliminary
Mismatch____________________Preliminary
Unexpected Adequate
Unexpected__________________Adequate
Non-sequitur Pusillanimous
Non-sequitur________________Pusillanimous
Extra-long word list from file 1 Rather long word from file.2 too
Extra-long word list from file 1Rather long word from file.2 too
根据您想要的格式的更精确定义,您可以进行无限的调整。除此之外,您还可以确保“必须具有下划线”示例中的第一个和第二个单词之间至少有3个下划线。您可以限制打印的字符串的长度。
代码应该检查它是否在前1023个字节内获得了换行符;它没有。
答案 1 :(得分:0)
如果我使用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
另外,如何格式化输入以生成两列。
嗯,您的问题没有提供足够的细节来提出确切的代码,例如:什么应该是列之间的间距,如果输入大于间距怎么办,等等。
无论如何 - 请参阅https://stackoverflow.com/a/45295262/4386427(由Jonathan Leffler提供)给你一些好的提示。