我正在尝试处理一些文件。文件路径存储在txt文件中。每行有4个文件名,每个文件名用空格分隔。我想在缓冲区中读取一行,将缓冲区划分为4个文件路径并在之后处理它们。当我完成后,我想对下一行的文件路径做同样的事情。
我有以下代码来处理文件名:
int i, j, check, fileidx, filenum;
char buf[100000], *testfile;
char filename_out[500], filename_mess[500], filename_ref[500], filename_dark[500];
filenum = getFileNumber("filelist.txt"); //get number of lines in the txt file
filelist = fopen("filelist.txt","r");
for (fileidx=0; fileidx<filenum; fileidx++){
memset(&filename_mess[0], 0, sizeof(filename_mess)); //clear filenames
memset(&filename_dark[0], 0, sizeof(filename_dark));
memset(&filename_ref[0], 0, sizeof(filename_ref));
memset(&filename_out[0], 0, sizeof(filename_out));
memset(&buf[0],0,sizeof(buf));
for (check = 0;check<fileidx+1;check++){ //up to the current file index
testfile = fgets(buf,100000,filelist); //get each line into the buffer
if ((testfile == NULL)&(check == fileidx)){ //if at the correct file index and line is empty
printf("Error in filelist (line %i is empty!)",check+1);
goto fileerror;
};
};
if (fileidx==filenum-1)
sprintf(buf,"%s\0",buf); //desperate try - not helping
if ((buf[0] == '\n') | (buf[0] == ' ') | (buf[0] == EOF)){
printf("Error in filelist (line %i)!",fileidx+1);
goto fileerror;
};
i=0;
while (buf[i]!=' '){ //while not hitting the first space
if (buf[i] == '\n'){ //if a filename is missing, the end of the line is found too early
printf("Error in filelist (line %i)! Element missing!",fileidx+1);
goto fileerror; //goto the next file
};
filename_mess[i] = buf[i]; //copy the buffer to the first filename array
i++;
};
i++; //skip the space between the filepaths
j = i; //save start of second filepath
while (buf[i]!=' '){ //repeat the process for second filename
if (buf[i] == '\n'){
printf("Error in filelist (line %i)! Element missing!",fileidx+1);
goto fileerror;
};
filename_ref[i-j] = buf[i];
i++;
};
i++;
j = i;
while (buf[i]!=' '){ //repeat process for third filename
if (buf[i] == '\n'){
printf("Error in filelist (line %i)! Element missing!",fileidx+1);
goto fileerror;
};
filename_dark[i-j] = buf[i];
i++;
};
i++;
j = i;
while ((buf[i]!='\n') & (buf[i]!= EOF) & (buf[i]!=' ')){ //we're at the last element, check for end of line or EOF here, too
if (buf[i] == ' '){
printf("Error in filelist (line %i)! Too many elements!",fileidx+1);
goto fileerror;
};
filename_out[i-j] = buf[i];
i++;
};
//read the files, process them
};
此代码对于除最后一行之外的所有行都可以正常工作。在最后一行中,只有最后一个元素存储在“filename_out”中,其他元素(mess,ref和dark)保持为空。缓冲区“buf”看起来很好,但是(用printf("%s",buf)
检查它显示了预期的行)。当我在文本文件中的最后一行下面添加一个空行时,读数正常。我还尝试使用sprintf(buf,"%s\n",buf)
每次将此(看似必要的)字符添加到缓冲区 - 没有用。
澄清:阅读包含
的txt文件R1E1 R1E2 R1E3 R1E4
R2E1 R2E2 R2E3 R2E4
会给我:
File1:
filename_mess = R1E1
filename_ref = R1E2
filename_dark = R1E3
filename_out = R1E4
File2:
filename_mess =
filename_ref =
filename_dark =
filename_out = R2E4
虽然它应该是:
File1:
filename_mess = R1E1
filename_ref = R1E2
filename_dark = R1E3
filename_out = R1E4
File2:
filename_mess = R2E1
filename_ref = R2E2
filename_dark = R2E3
filename_out = R2E4
在文本文件的末尾添加一个空行将返回:
File1:
filename_mess = R1E1
filename_ref = R1E2
filename_dark = R1E3
filename_out = R1E4
File2:
filename_mess = R2E1
filename_ref = R2E2
filename_dark = R2E3
filename_out = R2E4
File3:
*Error Message*
编辑:删除了一些错误。
答案 0 :(得分:0)
for (fileidx=0; fileidx<filenum-1; fileidx++)
这适用于一个行文件吗?不应该有&lt; =?
答案 1 :(得分:0)
删除require
确实有效。将buf[i]== EOF
添加到每个'\n'
的末尾,然后检查buf
而不是buf[i]=='\n'
。
答案 2 :(得分:0)
您可以在cplusplus参考中查看link处的链接,该链接描述了按顺序从文件中读取行的直接方式。
cplusplus参考中的这个link描述了基于分隔符对字符串进行标记的直接方式(将该行拆分为4个单独的字符串)
使用这些链接,我设法将以下代码放在一起,似乎做了你想做的事情
//#include "file_processor_main_stackoverflow_question.h" //this is my own stuff
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <stdlib.h>
#include <assert.h>
static void parse_line(char *line, char *res[], const int n_words, const int word_length);
int file_processor_so_main(int argc, char **argv) {
int n_words = 4;
int word_length = 1000;
FILE *f = NULL;
char buf[9999];
printf("file processor main\n");
if (argc < 2) {
printf("usage: file_processor [file_name]\n");
return 0;
}
printf("%s\n", argv[1]);
f = fopen(argv[1], "r");
if (!f) {
printf("failed to open file: %s\n", argv[1]);
return 0;
}
//file was opened successfully
while (!feof(f)) {
int i; char *res[4];
if (fgets(buf, 9999, f) == NULL)
break;
printf("buf: %s\n", buf);
//initialize res
for (i = 0; i < n_words; ++i) {
res[i] = (char*)calloc(word_length, sizeof(char));
}
parse_line(buf, res, n_words, word_length);
for (i = 0; i < n_words; ++i) {
printf("res[%d]: %s\n", i, res[i]);
//process file at res[i]
free(res[i]);
}
}
fclose(f);
return 0;
}
void parse_line(char *line, char *res[], const int n_words, const int word_length) {
int count = 0;
char *buf = strtok(line, " ");
while (buf != NULL && count < n_words) {
printf("%s ", buf);
assert(strlen(buf) < word_length);
strcpy(res[count++], buf);
buf = strtok(NULL, " ");
}
printf("\n");
}