C 处理文件时的混乱
我正在编写一个程序,它从一个文件中提取一个字符串,从另一个文件中提取一个字符串,然后将它们分别写入第三个文件的列中。我真的有两个问题,如果我使用fgets从文件中获取字符串,它会停在行的末尾。它会自动知道下一个字符串从下一行开始。另外,如何格式化输入以生成两列。例如 第一个字符串是第一个文件中的“John”。 第二个字符串是第二个文件中的“applesed” 第三个文件中会有“John 第三个文件的第二行将显示“Benny\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuC 处理文件时的混乱,c,string,file,format,C,String,File,Format,我正在编写一个程序,它从一个文件中提取一个字符串,从另一个文件中提取一个字符串,然后将它们分别写入第三个文件的列中。我真的有两个问题,如果我使用fgets从文件中获取字符串,它会停在行的末尾。它会自动知道下一个字符串从下一行开始。另外,如何格式化输入以生成两列。例如 第一个字符串是第一个文件中的“John”。 第二个字符串是第二个文件中的“applesed” 第三个文件中会有“John 第三个文件的第二行将显示“Benny\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
只是格式化列。您想要下划线,还是空格就足够了?使用空格更简单。您可以阅读的规格 查看格式字符串的详细功能
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从文件中获取字符串,它将停止在行的末尾。它会自动知道如何启动吗