我正在尝试读取文件和下一行的行,以查看它是否以空格开头,例如:
First line
second line
Third line
fourth line
当我正在读取文件时,我想检查并查看以下行是否有空格,如果有,我想strcat这两行(在这种情况下是第一行和第二行)。
所以对于第一个例子:
1。)在第一行读取,向前读到第二行,看到它们是一个空格,并且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被执行时,它会读取第一行,它看到没有空格,然后转到下一行,看到有空格,存储它,但现在fileBuffer不再包含第一行了,但第二个。
所以当我下一次strcat时,我没有得到“First linesecond line”的正确结果。
相反,我得到第三行的结果与第二行混合,这不是我想要的。
我不确定如何解决我的逻辑,任何想法?
答案 0 :(得分:2)
修复你的逻辑:
#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;
}
答案 1 :(得分:1)
您需要处理几个额外的注意事项。第一个是,您需要删除'\n'
读取中的尾随fgets
包含。为此,您需要读取行的长度。然后,您可以通过使用 nul-terminatedating 字符覆盖它来删除试用'\n'
。 e.g:
while (fgets (buf1, MAXC, fp)) {
size_t len1 = strlen (buf1); /* get length */
if (len1 && buf1[len1-1] == '\n') buf1[--len1] = 0; /* remove \n */
另一个考虑因素是如何管理分配和释放用于组合线的内存。由于您从相对固定长度的字符串中读取最后一行的第一部分然后第二部分,因此使用2个静态缓冲区更有意义,一个用于读取该行,以及一个用于保存第一个副本的行。您可以分配最终结果。 e.g。
enum { MAXC = 100 }; /* constant for max characters */
...
int main (int argc, char **argv) {
char buf1[MAXC] = {0};
char buf2[MAXC] = {0};
char *both = NULL;
一旦准备好组合线的两个部分,就可以准确分配所需的空间,例如
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'
仔细看看,如果您有任何问题,请告诉我。
答案 2 :(得分: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;
}