如何在c中通过strtok复制返回的令牌
How to copy the returned token by strtok in c
当我尝试按照本论坛其他答案的建议通过 strcpy 复制 strtok 时。我没有得到相应的号码。文件格式在每一行上类似于 43,789,127.0.0.1。但是我在 temp[2] 位置得到 127 应该是 127.0.0.1 。我在这里错过了什么?
FILE *f = fopen("somefile", "r");
char *temp[3];
temp[0] = malloc(20);
temp[1] = malloc(20);
temp[2] = malloc(20);
const char s[1] = ",";
char *pch;
if(f != NULL)
{
char line[1024];
while(fgets(line, sizeof line, f) != NULL)
{
pch = strtok(line, s);
for(int i = 0; i<3; i++)
{
strcpy(temp[i],pch);
pch = strtok (NULL, s);
}
}
fclose(f);
} else
{
perror("somefile");
}
for(int i = 0; i<3; i++)
{
printf ("%s\n",temp[i]);
}
s
不是正确的 C 字符串:const char s[1] = ",";
将其定义为大小为 1,没有空终止符。
改用这个:
const char *s = ",";
请注意,少于 2 个逗号的行将导致程序出现未定义的行为,因为您没有检查 strtok()
returns 非 NULL 指针。这是使用 sscanf()
的替代方法:
#include <stdio.h>
int main(void) {
FILE *fp = fopen("somefile", "r");
char temp[3][20];
if (fp != NULL) {
char line[1024];
while (fgets(line, sizeof line, fp) != NULL) {
if (sscanf(line, "%19[^,],%19[^,],%19[^\n]", temp[0], temp[1], temp[2]) == 3) {
printf("%s\n%s\n%s\n\n", temp[0], temp[1], temp[2]);
}
}
fclose(fp);
}
return 0;
}
但是请注意,上面的代码将无法解析带有空字段的行,例如 ,,
,因为 sscanf()
需要 %[^,]
转换说明符的非空字符串。
另请注意,strtok()
也不适合此类解析,因为它将分隔符序列视为单个分隔符,这对于白色 space 是可以的,但对于 ,
可能不正确.
以下建议代码:
- 干净地编译
- 一致缩进
- 水平和垂直间距适当
- 更正了已发布代码中的所有已知问题
- 正确检查并处理错误
- 正确显示文件中所有行的参数
- 消除不需要的变量
现在是代码
#include <stdio.h> // fopen(), fclose(), fgets(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strtok(), strcpy()
#define MAX_LENGTH 20
#define MAX_PARAMETERS 3
int main( void )
{
FILE *f = fopen( "somefile", "r" );
if( !f )
{
perror( "fopen to read somefile failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
char *temp[ MAX_PARAMETERS ];
if( NULL == ( temp[0] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
if( NULL == ( temp[1] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
if( NULL == ( temp[2] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
char line[1024];
while( fgets(line, sizeof line, f) )
{
int i;
char *pch = strtok( line, "," );
for( i = 0; i<3 && pch; i++ )
{
strcpy( temp[i], pch );
pch = strtok ( NULL, "," );
}
if( MAX_PARAMETERS != i )
{
printf( "failed to extract all parameters from line: %s\n", line );
}
else
{
for( int j = 0; j<MAX_PARAMETERS; j++ )
{
printf( "%s\n", temp[j] );
}
}
}
fclose( f );
} // end function: main
当我尝试按照本论坛其他答案的建议通过 strcpy 复制 strtok 时。我没有得到相应的号码。文件格式在每一行上类似于 43,789,127.0.0.1。但是我在 temp[2] 位置得到 127 应该是 127.0.0.1 。我在这里错过了什么?
FILE *f = fopen("somefile", "r");
char *temp[3];
temp[0] = malloc(20);
temp[1] = malloc(20);
temp[2] = malloc(20);
const char s[1] = ",";
char *pch;
if(f != NULL)
{
char line[1024];
while(fgets(line, sizeof line, f) != NULL)
{
pch = strtok(line, s);
for(int i = 0; i<3; i++)
{
strcpy(temp[i],pch);
pch = strtok (NULL, s);
}
}
fclose(f);
} else
{
perror("somefile");
}
for(int i = 0; i<3; i++)
{
printf ("%s\n",temp[i]);
}
s
不是正确的 C 字符串:const char s[1] = ",";
将其定义为大小为 1,没有空终止符。
改用这个:
const char *s = ",";
请注意,少于 2 个逗号的行将导致程序出现未定义的行为,因为您没有检查 strtok()
returns 非 NULL 指针。这是使用 sscanf()
的替代方法:
#include <stdio.h>
int main(void) {
FILE *fp = fopen("somefile", "r");
char temp[3][20];
if (fp != NULL) {
char line[1024];
while (fgets(line, sizeof line, fp) != NULL) {
if (sscanf(line, "%19[^,],%19[^,],%19[^\n]", temp[0], temp[1], temp[2]) == 3) {
printf("%s\n%s\n%s\n\n", temp[0], temp[1], temp[2]);
}
}
fclose(fp);
}
return 0;
}
但是请注意,上面的代码将无法解析带有空字段的行,例如 ,,
,因为 sscanf()
需要 %[^,]
转换说明符的非空字符串。
另请注意,strtok()
也不适合此类解析,因为它将分隔符序列视为单个分隔符,这对于白色 space 是可以的,但对于 ,
可能不正确.
以下建议代码:
- 干净地编译
- 一致缩进
- 水平和垂直间距适当
- 更正了已发布代码中的所有已知问题
- 正确检查并处理错误
- 正确显示文件中所有行的参数
- 消除不需要的变量
现在是代码
#include <stdio.h> // fopen(), fclose(), fgets(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strtok(), strcpy()
#define MAX_LENGTH 20
#define MAX_PARAMETERS 3
int main( void )
{
FILE *f = fopen( "somefile", "r" );
if( !f )
{
perror( "fopen to read somefile failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
char *temp[ MAX_PARAMETERS ];
if( NULL == ( temp[0] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
if( NULL == ( temp[1] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
if( NULL == ( temp[2] = malloc( MAX_LENGTH ) ) )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
char line[1024];
while( fgets(line, sizeof line, f) )
{
int i;
char *pch = strtok( line, "," );
for( i = 0; i<3 && pch; i++ )
{
strcpy( temp[i], pch );
pch = strtok ( NULL, "," );
}
if( MAX_PARAMETERS != i )
{
printf( "failed to extract all parameters from line: %s\n", line );
}
else
{
for( int j = 0; j<MAX_PARAMETERS; j++ )
{
printf( "%s\n", temp[j] );
}
}
}
fclose( f );
} // end function: main