manual split function in C
This code is driving me up the wall. The goal is to split to char[] based on a comma. It works in java. But prints weird output in C. The error I suspect is at 28 on the second iteration of the loop where I tried to add 5 the array turns into weird characters.
#include <stdio.h>
#include <string.h>
main()
{
char asshat[] = {'4','5','5',',','7','4','7','\0'};
int firstSize = 0;//
int secondSize = 0;//
//new = 4 \0 \0
char first[] = {'0', '\0'};//
//new =
char second[] = {'0', '\0'};//
char *first_ptr = first;
char *second_ptr = second;
int takingFirst = 1;
int takingSecond = 0;
int i;
for (i = 0; i < strlen(asshat); i++)
{
if (asshat[i] != ',')
{
if (takingFirst == 1)
{
first_ptr[firstSize] = asshat[i];//ERROR here when you add 5 you s**t bricks
firstSize++;
if (asshat[i+1] != ',')
{
char new[firstSize+2];
int k;
for (k = 0; k < strlen(first_ptr); k++)
{
new[k] = first_ptr[k];
}
new[firstSize] = '0';
new[firstSize+1] = '\0';
first_ptr = new;
}
}
if (takingSecond == 1)
{
second_ptr[secondSize] = asshat[i];
secondSize++;
if (asshat[i+1] != '\0')
{
char new[secondSize+2];
int k;
for (k = 0; k < strlen(second_ptr); k++)
{
new[k] = second_ptr[k];
}
new[secondSize+1] = '\0';
second_ptr = new;
开发者_StackOverflow中文版 }
}
}
else
{
takingFirst = 0;
takingSecond = 1;
}
}
printf("%d\n",strlen(first_ptr));
printf("%c%c%c\n",first_ptr[0],first_ptr[1],first_ptr[2]);
printf("%s\n",first_ptr);
printf("%d\n",strlen(second_ptr));
printf("%c%c%c\n",second_ptr[0],second_ptr[1],second_ptr[2]);
printf("%s\n",second_ptr);
}
You declare new
as a local variable and let first_ptr
point to the memory location of that local variable:
{
char new[firstSize+2];
...
first_ptr = new;
}
Then the local variable goes out of scope and its memory will be reused by other variables/... created in the future. first_ptr
still points to that memory location, but the array that was there doesn't exist anymore. When try to access the array through first_ptr
anything could happen and you most likely will find unexpected values.
It's very hard to read what your solution is doing. I tried reimplementing it to be simpler while maintaining your pointer play:
#include <stdio.h>
int
main(int argc, char *argv[])
{
/* Keeping variable names consistent :) */
char asshat[] = "456,747";
char *first = asshat, *second = asshat, *c = asshat;
while (*c) {
if (*c == ',') {
*c = '\0'; second = ++c;
} else c++;
}
printf("first: %s\nsecond: %s\n", first, second);
return 0;
}
This produces:
first: 456
second: 747
You can do it with slicing in roughly one line :)
Assuming there is at least one ,
...
char asshat[] = "hello,world";
char* second = asshat;
while (*second++ != ',');
*(second - 1) = 0;
printf("first: %s; second: %s\n",asshat,second);
You can build on that to check if there is a comma at all (it will crash horribly if there isn't).
To split a string in C, I suggest you leave the hard work for strtok(). Dont re-invent the wheel if you don't have to.
I assume you're trying to copy the "455" to first
and the "747" to second
? If so, you haven't allocated enough space for that. char first[] = {'0', '\0'}
only allocates an array of size 2; you'll need 4. Same for second
.
You're trying to solve too many problems at the same level by figuring out where you are in the original string and whether you're trying to copy to first
or second
and tracking how long each substring is; this is contributing to your confusion and making the problem harder than it needs to be.
Start by separating the concerns: you need one function to find the next substring in your input, and another to copy that substring into its destination.
Frankly, the best way to split up the string is to use any one of the standard library functions strtok
, strchr
, or strcspn
, and use either strcpy
or strncpy
to copy the substring to the destination arrays. There are a lot of very good reasons not to use strtok
, but it is one of the easiest methods to do what you're looking for.
Here's the general procedure for using strtok
:
char *token = strtok(asshat, ","); // return a pointer to the substring
// before the first comma
while (token)
{
strcpy(destination[i++], token); // assumes destination exists and is
// large enough to hold the token contents
token = strtok(NULL, ","); // find the next substring in the sequence;
// pass NULL to indicate you're continuing
// in the same string
}
As I mentioned above, there are reasons you don't want to use strtok
. It modifies the input string (replaces the delimiter with a 0), so you can't use it on a string literal. You may also want to preserve your original string. In addition, strtok
is not reentrant nor thread-safe.
Applying it to your specific case, you could do something like:
#include <stdio.h>
#include <string.h>
int main(void)
{
char asshat[] = "455,747";
char first[4] = "";
char second[4] = "";
char *destination[] = {first, second, NULL};
size_t i = 0;
char *token = strtok(asshat, ",");
while (token && destination[i]) // continue while we get a token AND
{ // there's a place to save it
strcpy(destination[i++], token);
token = strtok(NULL, ",");
}
printf("first = %s\n", first);
printf("second = %s\n", second);
return 0;
}
精彩评论