我有一个关于从文件中读取包含空格的字符串的问题。 这是我的函数,它从文件中读取数据并将其写入结构数组。 但是,如果第一个字符串的输入包含两个字符串并且它们之间有空格,则第一个字符串转到第一个参数,第二个字符串转到第二个参数。 如何从文件中分割行,使必要的数据转到指定的结构字段? 谢谢!
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++;
}
}
}
答案 0 :(得分:3)
由于起始位置和结束位置的空格数未知,因此使用scanf()方法会很复杂。但是,它可以使用更多的旧学校进行解析。方法....
"some place 13:40 10000 some other place 14:45 10120"
首先,将每一行视为包含两个'路径点&#39 ;; a'开始'和'结束'然后通过使用单个" way-point"来简化解析各个路点的过程。解析方法。
"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;
}