gpt4 book ai didi

C-divide 输入字符串 - 分割错误

转载 作者:太空宇宙 更新时间:2023-11-04 04:21:50 29 4
gpt4 key购买 nike

我的代码将以这种方式工作:

input : a[]="create  /dir/bar"

并保存在这个字符串中:

b[]=create
c[]=/dir/bar

还有一种情况是我保存了另外一个字符串:(举例)

a[]=write /foo/bar  "test"

b[]= write
c[]=/foo/bar
d[]=test (without the "")

我的代码是这样的:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SPACE ' '

void divide(char a[], char b[], char c[], char d[]);

int main(int argc, char const *argv[]) {
char a[50+1];
char b[50+1];
char c[50+1];
char d[50+1];
int i;

scanf("%s\n", a);

divide(a, b, c, d);

for(i=0; b[i]!='\0'; i++)
printf("%s %s %s \n", b, c, d);

return 0;
}



void divide(char a[], char b[], char c[], char d[]){
int i, j;

for(i=0; a[i]!=SPACE; i++)
b[i]=a[i];

b[i]='\0';

for(; a[i]==SPACE; i++)
;

for(j=0; a[i]!='\0'; i++, j++)
c[j]=a[i];

c[j]='\0';
for(; a[i]==SPACE; i++)
;

if(a[i]=='"'){
i++;
for(j=0; a[i]!='"'; i++)
d[j]=a[i];

d[j]='\0';

return;
}
}

但是对于程序获取输入后的段错误不起作用。问题出在哪里?

我不能使用 malloc,因为它会花费太多时间来工作(我必须得到数千行)并且不遵守限制。 (我在大学里为一个项目工作)

最佳答案

您可能会使这比需要的更困难。是的,您可以通过重复调用 sscanf 或使用 scanf 重复读取来标记字符串,但 C 库提供了一个工具来标记一行文本中的单词。足够巧妙地命名为 strtok

您只需声明一个常量字符串,其中包含您希望用来打断单词的分隔符(例如 delims = "\t"; 以在空格或制表符上打断单词,然后调用 strtok (str, delims) 返回第一个标记(单词),然后循环重复调用 strtok (NULL, delims) 来解析剩余的单词(或者直到你到达你的最多 3 个单词)。

(注意strtok的第一次调用使用str作为第一个参数,而所有后续调用都使用NULL)

这是一种更灵活的方式来处理字符串中未知数量的标记。

不要使用 a[]b[]c[] 等。考虑只使用一个 buf[] 将输入行读入,然后是一个字符串数组来保存参数(这允许您在 strtok< 循环期间使用 index 变量 将正确的字符串分配并复制到关联的索引)。

在这种情况下,不要使用 void 作为返回值。为什么不使用有意义的返回(如文本行中的参数数量)。这样,您就知道在除法函数中读取(或标记化)了多少。给它一个可以提供有用信息的返回,例如

size_t divide (char *buf, char (*params)[MAXC+1]);

现在将返回一个 size_t 类型,其中包含每次调用 divide 产生的参数数量。

总而言之,(并使用 fgets 读取整行输入),您可以执行如下操作:

#include <stdio.h>
#include <string.h>

enum { MAXP = 3, MAXC = 50 }; /* max parameters & chars */

size_t divide (char *buf, char (*params)[MAXC+1]);

int main (void) {

char buf[MAXC * 4 + 1] = "";
char params[MAXP][MAXC + 1]; /* array to hold 3 parameters */
size_t i, len, nparams = 0;

/* use fgets for line-oriented user input */
printf ("\nenter commands: ");
if (!fgets (buf, sizeof buf, stdin)) {
fprintf (stderr, "error: insufficient input.\n");
return 1;
}

len = strlen (buf); /* get length */
if (buf[len - 1] == '\n') /* validate last char is '\n' */
buf[--len] = 0; /* overwrite with nul-terminating char */
else { /* short read -- handle error */
fprintf (stderr, "error: incomplete input read.\n");
return 1;
}

nparams = divide (buf, params);

for (i = 0; i < nparams; i++)
printf ("parameter[%zu] : %s\n", i, params[i]);

return 0;
}

/* divide using strtok */
size_t divide (char *buf, char (*params)[MAXC+1])
{
char *delims = " \t", /* delimiters for strtok */
*p = buf; /* pointer to buf */
size_t n = 0; /* var to return number of params */

p = strtok (buf, delims); /* tokenize fist paramter */

while (p) { /* now loop until all words exhausted or limit reached */
strncpy (params[n++], p, MAXC); /* copy token to params array */
if (n == MAXP) /* check if limit reached */
break;
p = strtok (NULL, delims); /* get next token */
}

return n; /* return the number of parameters found */
}

示例使用/输出

$ /bin/splitparams

enter commands: create /dir/bar
parameter[0] : create
parameter[1] : /dir/bar

$ ./bin/splitparams

enter commands: write /foo/bar "test"
parameter[0] : write
parameter[1] : /foo/bar
parameter[2] : "test"

或者提供一堆额外的单词(以验证仅处理 3 个单词)

$ ./bin/splitparams

enter commands: write /foo/bar "test" and some more stuff
parameter[0] : write
parameter[1] : /foo/bar
parameter[2] : "test"

关于C-divide 输入字符串 - 分割错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46138279/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com