[英]Reading string with spaces from file in c
我有一个关于从文件读取包含空格的字符串的问题。 这是我的功能,该功能从文件读取数据并将其写入结构数组。 但是,如果第一个字符串的输入包含两个字符串以及它们之间的空格,则第一个字符串将进入第一个参数,第二个字符串将进入第二个参数。 如何以某种方式将文件中的行分开,以使必要的数据进入结构的指定字段? 谢谢!
void readFileToDiary(FILE* file, drivingDiary* diaryTemp){
int i = 0;
file = fopen("test.txt", "r");
if (file == NULL)
printf("\nError opening file!\n");
else{
while (!feof(file)){
fscanf(file, "%s %s %d %s %s %d", diaryTemp[i].locationStart,
diaryTemp[i].timeStart, &diaryTemp[i].odometerStart,
diaryTemp[i].locationEnd, diaryTemp[i].timeEnd,
&diaryTemp[i].odometerEnd);
i++;
}
}
}
文件中的示例行包含:某个地方13:40 10000另一个地方14:45 10120
所以,
"some place" -> first field of structure,
13:40 -> second field,
10000 -> third field,
"some other place" -> fourth field,
14:45 -> fifth filed,
10120 -> sixth field.
UPD工作版本在这里(无需fscanf()检查)!
void readFileToDiary(FILE* file, drivingDiary* diary){
int i = 0;
file = fopen("test.txt", "r");
if (file == NULL)
printf("\nError opening file!\n");
else{
while(fscanf(file, " %[a-zA-Z ]%[0-9:]%d %[a-zA-Z ]%[0-9:]%d%*[\n]",
diary[i].locationStart,
diary[i].timeStart,
&diary[i].odometerStart,
diary[i].locationEnd,
diary[i].timeEnd,
&diary[i].odometerEnd) != EOF)
i++;
}
}
}
由于开始和结束位置的空格数未知,因此使用scanf()方法将很复杂。 但是,可以使用更“古老”的方法来解析它。
"some place 13:40 10000 some other place 14:45 10120"
首先,将每条线视为包含两个“航路点”; “开始”和“结束”。 然后,使用单个“航路点”解析方法简化对各个航路点的解析。
"some place 13:40 10000", "some other place 14:45 10120"
因此,将有几种方法来构建“航点”解析器。 当我看着问题时,我不想开始使用空格字符作为分隔符。 我想找到其他起点。
每个航路点都包含一个“:”字符,因此我从此处开始。 我从':'字符离开,找到空格,并将空格转换为'\\ 0'字符串终止字符。 这就隔离了航路点的“位置”。
然后,从':'处继续,找到空格,并将空格转换为'\\ 0'字符串终止符。 这就隔离了航路点的“时间”。
使用strtoul()可以轻松隔离航路点的里程表部分。
我的代码如下:
/***************************************************************************
** Compiler setup
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef struct DRIVING_WAYPOINT_S
{
char *location;
char *time;
long odometer;
} DRIVING_WAYPOINT_T;
typedef struct DRIVING_DIARY_S
{
DRIVING_WAYPOINT_T start;
DRIVING_WAYPOINT_T end;
} DRIVING_DIARY_T;
/***************************************************************************
** Parse a waypoint.
*/
int ParseRecord(
char *I__string,
char **_O_string,
DRIVING_WAYPOINT_T *I__waypoint
)
{
int rCode=0;
char *cp, *space;
/* Parse location */
cp=strchr(I__string, ':'); /* Find the first ocurrance of ':' */
if(NULL == cp)
{
rCode=EINVAL;
fprintf(stderr, "Parse error. Time does not contain a ':'\n");
goto CLEANUP;
}
space = cp;
while(' ' != *space)
--space;
*space = '\0';
I__waypoint->location = strdup(I__string);
/* Parse time */
cp = space + 1;
space=strchr(cp, ' ');
if(NULL == space)
{
rCode=EINVAL;
fprintf(stderr, "Parse error. No space following time\n");
goto CLEANUP;
}
*space='\0';
I__waypoint->time = strdup(cp);
/* Parse odometer */
cp = space+1;
I__waypoint->odometer = strtol(cp, &cp, 10);
while(' ' == *cp)
++cp;
if(_O_string)
*_O_string = cp;
CLEANUP:
return(rCode);
}
/*******************************************************************************
** Parse the diary file.
*/
int ReadFileToDiary(
FILE *I__fp,
DRIVING_DIARY_T **IO_diary,
int *IO_diaryEntries
)
{
int rCode = 0;
char line[255+1];
for(;;)
{
DRIVING_DIARY_T *tmp;
char *cp;
/* Read the next line from the file. */
errno=0;
if(NULL == fgets(line, sizeof(line), I__fp))
{
if(feof(I__fp))
break;
rCode=errno;
fprintf(stderr, "fgets() reports: %d.\n", errno);
goto CLEANUP;
}
/* Expand the diary array for one more entry. */
tmp=realloc(*IO_diary, ((*IO_diaryEntries)+1) * sizeof(DRIVING_DIARY_T));
if(NULL == tmp)
{
rCode=ENOMEM;
fprintf(stderr, "realloc() failed.\n");
goto CLEANUP;
}
*IO_diary = tmp;
memset(&(*IO_diary)[*IO_diaryEntries], '\0', sizeof(DRIVING_DIARY_T));
/* Check for empty string. */
if('\0' == *line)
continue;
/* Parse the 'start' waypoint. */
rCode=ParseRecord(line, &cp, &(*IO_diary)[*IO_diaryEntries].start);
if(rCode)
{
fprintf(stderr, "ParseRecord(start) reports: %d\n", rCode);
goto CLEANUP;
}
/* Parse the 'end' waypoint. */
rCode=ParseRecord(cp, NULL, &(*IO_diary)[*IO_diaryEntries].end);
if(rCode)
{
fprintf(stderr, "ParseRecord(end) reports: %d\n", rCode);
goto CLEANUP;
}
/* Increment the 'diary entries' counter. */
(*IO_diaryEntries)++;
}
CLEANUP:
return(rCode);
}
/*******************************************************************************
** Free the diary array.
*/
int DiaryFree(
DRIVING_DIARY_T *diary,
int diaryEntries
)
{
int rCode=0;
int nCnt;
for(nCnt=0; nCnt<diaryEntries; ++nCnt)
{
free(diary[nCnt].start.location);
free(diary[nCnt].end.location);
free(diary[nCnt].start.time);
free(diary[nCnt].end.time);
}
free(diary);
return(rCode);
}
/*******************************************************************************
** Program start.
*/
int main()
{
int rCode = 0;
FILE *fp = NULL;
DRIVING_DIARY_T *diary = NULL;
int diaryEntries = 0;
int nCnt;
/* Open the data file. */
errno=0;
fp = fopen("test.txt", "r");
if(NULL == fp)
{
rCode=errno;
fprintf(stderr, "fopen() failed. errno:%d\n", errno);
goto CLEANUP;
}
/* Parse the file into the dynamic diary array. */
rCode=ReadFileToDiary(fp, &diary, &diaryEntries);
if(rCode)
{
fprintf(stderr, "ReadFileToDiary() reports: %d\n", rCode);
goto CLEANUP;
}
/* Print out the array. */
for(nCnt=0; nCnt < diaryEntries; ++nCnt)
{
printf("[%d] %s %s %ld %s %s %ld\n",
nCnt,
diary[nCnt].start.location,
diary[nCnt].start.time,
diary[nCnt].start.odometer,
diary[nCnt].end.location,
diary[nCnt].end.time,
diary[nCnt].end.odometer
);
}
CLEANUP:
if(diary)
DiaryFree(diary, diaryEntries);
if(fp)
fclose(fp);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.