我试图从一个文件的不同部分拆分一行,由一个空格分隔,但它不起作用...所以我的问题是:如何将我的行拆分为不同的部分并为每个部分执行此操作单行文件,然后将这些部分放入动态分配的 vector/矩阵中?或者也可以按列。告诉我你认为合适的。
文件看起来像这样:
BERLIN CAR 1 U
BERLIN CAR 1 R
BUCHAREST JACKET 2 D
NEW_YORK DOLL 7 U
BERLIN ROBOT 5 L
BUCHAREST BALL 4 L
我想做这个。 示例:
Locations[i]={"BERLIN","BERLIN","BUCHAREST","NEW_YORK"."BERLIN","BUCHAREST"}
TOYS[j]={"CAR","CAR","JACKET","DOLL","ROBOT","BALL"}
NUMBER[k]={1,1,2,7,5,4}
LETTER[l]={'U','R','D','U','L','L'}
到目前为止我的代码(MAX_STRING_LENGTH 定义为 30):
int i;
char *p,**a,delim[]=" ";
a=malloc(100 * sizeof(char));
for(i = 0; i < 100; i++)
{
a[i]=calloc(MAX_STRING_LENGTH,sizeof(char));
}
while(!feof(stdin))
{
fgets(*a,500,stdin);
p=strtok(*a,delim);
}
最佳答案
strtok
是正确的功能,但是您使用它是错误的。
man strtok
The
strtok()
function breaks a string into a sequence of zero or more nonempty tokens. On the first call tostrtok()
, the string to be parsed should be specified instr
. In each subsequent call that should parse the same string,str
must beNULL
.
我将引用中最重要的部分加粗了。
另请记住 strtok
修改源,如果你需要源
之后,您必须复制一份。
// assuming that line is either a char[] or char*
char *token = strtok(line, " ");
if(token == NULL)
{
// error detection
}
while(token = strtok(NULL, " "))
{
// do the work
}
另外我建议不要使用 sizeof(<data type>)
在
malloc
/calloc
/realloc
电话。很容易忽略 *
和做
错误。更好:
int *myarray = malloc(size * sizeof *myarray);
// or
int *mayarray = calloc(size, sizeof *myarray);
使用 sizeof *var
更好,因为它总是会返回正确的尺寸。
最后一件事:
while(!feof(stdin))
参见 Why is “while ( !feof (file) )” always wrong?
更好
char buffer[1024];
while(fgets(buffer, sizeof buffer, stdin))
{
// do the work here
}
编辑
这里有一个使用 strtok
的示例实现.我的实现使用
MAP
的数组秒。看看我构造/破坏 MAP
的方式对象以及内存是如何分配的。显然,这可以用更少的代码和更少的代码来完成 strdup
s,但我认为这更准确地展示了如何使用这些功能。您可以将此代码用作您的基础或仅将其用作基本想法。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef struct{
char *destination;
char *type_present;
int no_available_presents;
char *direction;
} MAP;
MAP *create_map(const char *dest, const char *type, int present, const char *dir);
void free_map(MAP *map);
void print_map(MAP *map);
MAP *create_map(const char *dest, const char *type, int present, const char *dir)
{
MAP *map = calloc(1, sizeof *map);
if(map == NULL)
return NULL;
int errors = 0;
if(!(map->destination = strdup(dest)))
errors++;
if(!(map->type_present = strdup(type)))
errors++;
if(!(map->direction = strdup(dir)))
errors++;
map->no_available_presents = present;
if(!errors)
return map;
free_map(map);
return NULL;
}
void free_map(MAP *map)
{
if(map == NULL)
return;
free(map->destination);
free(map->type_present);
free(map->direction);
free(map);
}
void print_map(MAP *map)
{
if(map == NULL)
{
puts("(null)");
return;
}
printf("destination: %s\n", map->destination);
printf("type: %s\n", map->type_present);
printf("present: %d\n", map->no_available_presents);
printf("direction: %s\n", map->direction);
}
int main(char argc, char **argv)
{
FILE *fp;
if(argc != 1 && argc != 2)
{
fprintf(stderr, "usage: %s [database]\n", argv[0]);
return 1;
}
if(argc == 1)
fp = stdin;
else
fp = fopen(argv[1], "r");
if(fp == NULL)
{
fprintf(stderr, "Could not open '%s': %s\n", argv[1], strerror(errno));
return 1;
}
MAP **maps = NULL;
size_t map_len = 0;
char line[1024];
const char *delim = " \r\n";
while(fgets(line, sizeof line, fp))
{
int pres;
char *dest = NULL, *type = NULL, *dir = NULL, *token;
token = strtok(line, delim);
dest = strdup(token);
token = strtok(NULL, delim);
type = strdup(token);
token = strtok(NULL, delim);
pres = atoi(token);
token = strtok(NULL, delim);
dir = strdup(token);
if(dest == NULL || type == NULL || dir == NULL)
{
// ignore line
free(dest);free(type);free(dir);
continue;
}
MAP *new_map = create_map(dest, type, pres, dir);
if(new_map == NULL)
{
// ignore line
free(dest);free(type);free(dir);
continue;
}
MAP **tmp_map = realloc(maps, (map_len + 1) * sizeof *tmp_map);
if(tmp_map == NULL)
{
// ignore line
free_map(new_map);
free(dest);free(type);free(dir);
continue;
}
maps = tmp_map;
maps[map_len++] = new_map;
free(dest);free(type);free(dir);
}
for(int i = 0; i < map_len; ++i)
{
print_map(maps[i]);
puts("---");
free_map(maps[i]);
}
free(maps);
if(fp != stdin)
fclose(fp);
return 0;
}
输出:
destination: BERLIN
type: CAR
present: 1
direction: U
---
destination: BERLIN
type: CAR
present: 1
direction: R
---
destination: BUCHAREST
type: JACKET
present: 2
direction: D
---
destination: NEW_YORK
type: DOLL
present: 7
direction: U
---
destination: BERLIN
type: ROBOT
present: 5
direction: L
---
destination: BUCHAREST
type: BALL
present: 4
direction: L
---
关于c - 如何在c中按行或列拆分文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48157653/