对于课堂作业,我们已被指示编写一个程序,该程序采用字符串和分隔符,然后采用"单词"并将它们存储在一个新的字符串数组中。即,输入("我的名字是","")将返回一个包含元素的数组" my" "名称" "是&#34 ;.
粗略地说,我所尝试的是:
使用名为number_of_delimeters()
的单独助手来确定字符串数组的大小
遍历初始数组,找到给定字符串中放置在数组中的元素数
在我的数组中为每个字符串分配存储空间
将元素存储在已分配的内存中
包含指令:
#include <stdlib.h>
#include <stdio.h>
这是单独的帮手:
int number_of_delimiters (char* s, int d)
{
int numdelim = 0;
for (int i = 0; s[i] != '\0'; i++)
{
if (s[i] == d)
{
numdelim++;
}
}
return numdelim;
}
`这是函数本身:
char** split_at (char* s, char d)
{
int numdelim = number_of_delimiters(s, d);
int a = 0;
int b = 0;
char** final = (char**)malloc((numdelim+1) * sizeof(char*));
for (int i = 0; i <= numdelim; i++)
{
int sizeofj = 0;
while (s[a] != d)
{
sizeofj++;
a++;
}
final[i] = (char*)malloc(sizeofj);
a++;
int j = 0;
while (j < sizeofj)
{
final[i][j] = s[b];
j++;
b++;
}
b++;
final[i][j+1] = '\0';
}
return final;
}
要打印:
void print_string_array(char* a[], unsigned int alen)
{
printf("{");
for (int i = 0; i < alen; i++)
{
if (i == alen - 1)
{
printf("%s", a[i]);
}
else
{
printf("%s ", a[i]);
}
}
printf("}");
}
int main(int argc, char *argv[])
{
print_string_array(split_at("Hi, my name is none.", ' '), 5);
return 0;
}
目前返回{嗨,我的名字是无。}
在做了一些研究之后,我意识到这个函数的目的与strtok相似或相同。但是,查看源代码对此有所帮助,因为它包含了我们尚未在课堂上使用的概念。
我知道这个问题很模糊,而且代码粗略阅读,但是你能指出这个问题的方法会立即出现问题吗?
答案 0 :(得分:0)
仅供参考:
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + fileName);
将修改您传入的数组!之后
request.setDestinationInExternalFilesDir(Context, Type, Path)
strtok
内容将是:
char test[] = "a b c ";
for(char* t = test; strtok(t, " "); t = NULL);
随后您将获得指向测试数组的指针:test
,{ 'a', 0, 'b', 0, 'c', 0, 0 }
,test + 0
,test + 2
。
strtok会记住你在内部传递给它的指针(很有可能,你在源代码中看到了一个test + 4
变量...)所以你可以(并且必须)传递{{ 1}}下次你调用它(只要你想对相同的源字符串进行操作)。
NULL
您只需返回数组,但是您正在丢失长度信息! 那么你想如何将长度传递给你的打印功能呢?
static
将失败,因为NULL
将始终返回本地系统上指针的大小(很可能是旧硬件上的8,可能是4)!
我的个人建议:创建一个空字符串终止的c字符串数组:
char** final = //...
return final;
void print_string_array(char* a[], unsigned int alen)
然后你的打印功能看起来像这样:
char** tokens = split_at(...);
print_string_array(tokens, sizeof(tokens));
不再有长度问题。实际上,这与C字符串使用的原理完全相同(终止空字符,还记得吗?)。
此外,这是您自己的代码中的问题:
sizeof(tokens)
为了完整性(这已经被n.m.发现,请参阅另一个答案):如果源字符串中没有尾随分隔符,
char** final = (char**)malloc((numdelim + 2) * sizeof(char*));
// ^ (!)
// ...
final[numdelim + 1] = NULL;
将超出输入字符串读取(这是未定义的行为,可能导致程序崩溃)。您还需要检查终止空字符:
void print_string_array(char* a[]) // no len parameter any more!
{
printf("{");
if(*a)
{
printf("%s", *a); // printing first element without space
for (++a; *a; ++a) // *a: checking, if current pointer is not NULL
{
printf(" %s", *a); // next elements with spaces
}
}
printf("}");
}
最后:您想如何处理后续分隔符?目前,您将在数组中插入空字符串?打印出你的字符串如下(带有两个分隔符号 - 我使用*和+像出生和死亡......):
while (j < sizeofj)
{
final[i][j] = s[b];
j++; // j will always point behind your string!
b++;
}
b++;
// thus, you need:
final[i][j] = '\0'; // no +1 !
你会看到。这是为了吗?
编辑2 :带指针算术的变体(仅限):
while (s[a] != d)
答案 1 :(得分:0)
该计划有几个问题。
while (s[a] != d)
错误,字符串中的最后一个单词后面没有分隔符。final[i][j+1] = '\0';
错了,j+1
太多了。{/ li>
答案 2 :(得分:0)
虽然我现在已经展示了一个更优雅的解决方案,但我已经找到并纠正了我的代码中的问题:
char** split_at (char* s, char d)
{
int numdelim = 0;
int x;
for (x = 0; s[x] != '\0'; x++)
{
if (s[x] == d)
{
numdelim++;
}
}
int a = 0;
int b = 0;
char** final = (char**)malloc((numdelim+1) * sizeof(char*));
for (int i = 0; i <= numdelim; i++)
{
int sizeofj = 0;
while ((s[a] != d) && (a < x))
{
sizeofj++;
a++;
}
final[i] = (char*)malloc(sizeofj);
a++;
int j = 0;
while (j < sizeofj)
{
final[i][j] = s[b];
j++;
b++;
}
final[i][j] = '\0';
b++;
}
return final;
}
我巩固了我之前作为辅助函数的功能,并修改了一些我错误增加的点。