字符串标记化 c 的麻烦
String tokenization c troubles
我有这段代码需要一个文件 "schedule.txt" 让用户输入 class 并显示 class 所在的时间,不幸的是我遇到了困难标记化...
int main(int argc, char *argv[])
{
// Declare variables
FILE *inp = NULL;
char str[200];
char class[7][20];
double times[15];
double times2[15];
int i;
const char delim[] = " 0123456789:";
// Open the file, quit if it fails...
inp = fopen(argv[1], "r");
if(inp == NULL){
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(1);
}
// Read the file and tokenize it for names of classes and times
i = 0;
while(fgets(str, 200, inp) != NULL){
str[strlen(str)-1] = '[=10=]';
char *classToken = strtok(str, "0123456789");
strcpy(class[i], classToken);
char *timeToken = strtok(NULL, " ");
times[i] = atof(timeToken);
i++;
}
for(i = 2; i < 6; i++){
printf("%f\n", times[i]);
}
return 0;
}
我希望将文件标记为两个不同的数组,一个包含 class 的字符串,另一个是没有“:”的时间,但是当我将分隔符作为数字时,它不允许我使用时间的第一个数字,但是当分隔符是“”时,字符串数组也包含时间,我该怎么做? 文件看起来像这样:
Class Schedule
Class Time
Physics 15:30
Calculus 9:00
Biology 14:30
Chemistry 11:30
你的问题有两个:第一个是strtok
修改了字符串,将找到的token分隔符替换为字符串终止符。
因此,如果您的输入字符串看起来像 "Physics 15:30"
,那么在第一次调用 strtok
之后,它将被修改为看起来像 "Physics :30"
。
解决方法是使用space(或制表符,或两者)作为token分隔符,然后在获取时跳过spaces下一个标记。
第二个问题是你使用atof
来获取时间。时间不是浮点值,尤其是当前的编号系统没有使用 :
来分隔整数和小数部分。更不用说 15:30
作为浮点数会是 15.30
,这与 15.50
不同(后者又与时间 15:50
不同)。
这两个问题的一个简单解决方案是使用 sscanf
代替将行解析为两个 字符串 .
主要问题是分隔符不合适。
具体来说,它会按如下方式进行分词。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct schedule {
char className[20];
int time;//minute
}Schedule;
int main(int argc, char *argv[]) {
FILE *inp;
char line[200];
char title[32];
char fieldName[2][20];
Schedule schedule[7];
int i;
if(argc != 2){
fprintf(stderr, "Usage : %s filename\n", argv[0]);
exit(1);
}
inp = fopen(argv[1], "r");
if(inp == NULL){
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(1);
}
fgets(title, sizeof title, inp);
fgets(line, sizeof line, inp);
char *token;
token = strtok(line, " \t\n");
strcpy(fieldName[0], token);
token = strtok(NULL, " \t\n");
strcpy(fieldName[1], token);
i = 0;
while(i < 7 && fgets(line, sizeof line, inp)){
token = strtok(line, " \t\n");//maybe "\t\n"
strcpy(schedule[i].className, token);
token = strtok(NULL, " \t\n");
schedule[i].time = atoi(token)*60 + atoi(strchr(token, ':')+1);//"hh:mm" : hh * 60 + mm
i++;
}
int n = i;
printf("%s", title);
printf("%-20s%s\n", fieldName[0], fieldName[1]);
for(i = 0; i < n; i++){
printf("%-20s%02d:%02d\n", schedule[i].className, schedule[i].time/60, schedule[i].time%60);
}
return 0;
}
我有这段代码需要一个文件 "schedule.txt" 让用户输入 class 并显示 class 所在的时间,不幸的是我遇到了困难标记化...
int main(int argc, char *argv[])
{
// Declare variables
FILE *inp = NULL;
char str[200];
char class[7][20];
double times[15];
double times2[15];
int i;
const char delim[] = " 0123456789:";
// Open the file, quit if it fails...
inp = fopen(argv[1], "r");
if(inp == NULL){
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(1);
}
// Read the file and tokenize it for names of classes and times
i = 0;
while(fgets(str, 200, inp) != NULL){
str[strlen(str)-1] = '[=10=]';
char *classToken = strtok(str, "0123456789");
strcpy(class[i], classToken);
char *timeToken = strtok(NULL, " ");
times[i] = atof(timeToken);
i++;
}
for(i = 2; i < 6; i++){
printf("%f\n", times[i]);
}
return 0;
}
我希望将文件标记为两个不同的数组,一个包含 class 的字符串,另一个是没有“:”的时间,但是当我将分隔符作为数字时,它不允许我使用时间的第一个数字,但是当分隔符是“”时,字符串数组也包含时间,我该怎么做? 文件看起来像这样:
Class Schedule
Class Time
Physics 15:30
Calculus 9:00
Biology 14:30
Chemistry 11:30
你的问题有两个:第一个是strtok
修改了字符串,将找到的token分隔符替换为字符串终止符。
因此,如果您的输入字符串看起来像 "Physics 15:30"
,那么在第一次调用 strtok
之后,它将被修改为看起来像 "Physics :30"
。
解决方法是使用space(或制表符,或两者)作为token分隔符,然后在获取时跳过spaces下一个标记。
第二个问题是你使用atof
来获取时间。时间不是浮点值,尤其是当前的编号系统没有使用 :
来分隔整数和小数部分。更不用说 15:30
作为浮点数会是 15.30
,这与 15.50
不同(后者又与时间 15:50
不同)。
这两个问题的一个简单解决方案是使用 sscanf
代替将行解析为两个 字符串 .
主要问题是分隔符不合适。
具体来说,它会按如下方式进行分词。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct schedule {
char className[20];
int time;//minute
}Schedule;
int main(int argc, char *argv[]) {
FILE *inp;
char line[200];
char title[32];
char fieldName[2][20];
Schedule schedule[7];
int i;
if(argc != 2){
fprintf(stderr, "Usage : %s filename\n", argv[0]);
exit(1);
}
inp = fopen(argv[1], "r");
if(inp == NULL){
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(1);
}
fgets(title, sizeof title, inp);
fgets(line, sizeof line, inp);
char *token;
token = strtok(line, " \t\n");
strcpy(fieldName[0], token);
token = strtok(NULL, " \t\n");
strcpy(fieldName[1], token);
i = 0;
while(i < 7 && fgets(line, sizeof line, inp)){
token = strtok(line, " \t\n");//maybe "\t\n"
strcpy(schedule[i].className, token);
token = strtok(NULL, " \t\n");
schedule[i].time = atoi(token)*60 + atoi(strchr(token, ':')+1);//"hh:mm" : hh * 60 + mm
i++;
}
int n = i;
printf("%s", title);
printf("%-20s%s\n", fieldName[0], fieldName[1]);
for(i = 0; i < n; i++){
printf("%-20s%02d:%02d\n", schedule[i].className, schedule[i].time/60, schedule[i].time%60);
}
return 0;
}