使用 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;
}
输出:
我正在尝试读取一个文件和下一行的一行,看看它是否以 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;
}
输出: