I got 2 arrays :
data[256] = "1#2#3#4#5"
question[256][256];
I need to split the number before the # into an array..
for example :
question[0][] = 1
question[1][] = 2
question[2][] = 3
question[3][] = 4
question[4][] = 5
It doesnt metter if I have the # in, or not.
This is what I wrote :
int i = 0, j = 0;
data = "1#2#3#4#5";
for (i = 0 ; i < strlen(data) ; i++)
{
for (j ; data[j] != '#' ; j++)
{
question[i][j] = data[j];
}
j++
}
printf ("%s\n", question);
The problem is, it works untill the first #, and then stops.
It only put the first # into question, and then stops.
(basiclly I'm supposed to get the same output for printing both data, and question).
There are a few problems.
First, printf only prints the string until the first terminating zero character ('\0'), which happens after the first "part" in question (even though there are other parts. Instead, you will need to print all:
for (i=0; i<255; ++i) {
printf("%s\n", question[i]);
}
Make sure you null-terminate ('\0') the rows of question before, so you don't print garbage for uninitialized rows. or just maintain the index of the last-good row and iterate until that
Also, the loop
for(j; data[j]!='#', j++)
will stop at the first '#', and all consequent iterations of the outside loop will evaluate the same j (which is the index of '#', so the loop is skipped in further iterations. You will need to advance j after the inner loop
you will also need to maintain a last-j position after the last '#' to be able to calculate the position of j from the last '#', so you can index into question[i] properly. set lastj to the value of j after is extra advancement suggested in the previous paragraph. Also, the second index of question should be j-lastj from now on.
Yet another thing about the inner loop: as it is, it will advance past the string in data after the last '#', so you will have to check for noll-termination as well.
Also, make sure you null-terminate the strings in question, otherwise printf will produce garbage (and possibly seg-fault when reaching memory not allocated to your progam). just write
question[i][j-lastj] = '\0';
after the inner loop. (j will have pointed after the last written index at the end of the inner loop)
Yet one more thing: do not iterate i until the length of data as you will not need to touch that many elements (and likely will overindex data in the inner loop). Use a while loop instead, incrementing i only until you have covered data with j in the inner loop
Note: look up strtok to make the tokenization easier on your part
I would use something like strchr to get the location of the next '#'.
The algorithm is something like this: You get the position of the next '#', and if there is none found then set next to the end of the string. Then copy from the current beginning of the string to next position into where you want it. Remember to terminate the copied string! Set the beginning of the string to one beyond next. Repeat until beginning is beyond the end of the data.
Edit: Code for my solution:
char *beg = data;
char *end = data + strlen(data); /* Points to one beyond the end of 'data' */
for (int i = 0; beg < end; i++)
{
char *next = strchr(beg, '#'); /* Find next '#' */
if (next == NULL)
break; /* No more '#' */
memcpy(question[i], beg, next - beg); /* Copy to array */
question[i][next - beg] = '\0'; /* Remember to terminate string */
beg = next + 1; /* Point to next possible number */
}
Note: Not tested. Might be one of with the copying, might have to be next - beg - 1. (Even after 25 years of C-programming, I always seem to get that wrong on the first try... :) )
There is a much simpler way to do this. Use strtok to tokenize the string by "#", and then use strcpy to copy the tokenized strings into your question array. For example (not tested):
char *pcur = data;
int i = 0;
do
{
if ((pcur = strtok(pcur, "#")) != NULL)
{
strcpy(question[i], pcur++);
printf ("%s\r\n", question[i++]);
}
}
while (pcur != NULL);
As shown in the above example, incrementing i moves the question array index to the next position, and incrementing pcur moves the tokenized string pointer past the nulled token for the next iteration through the loop.
See also:
http://msdn.microsoft.com/en-us/library/2c8d19sb.aspx
http://msdn.microsoft.com/en-us/library/kk6xf663.aspx
Related
The task is to ask user from which character and till where he wants to create another string.
int main()
{
char a[]="Working with stirng is fun";
printf("%s",a);
int s,e,j=0;
scanf("%d%d",&s,&e);
char b[e-s+2];
for(int i=s-1;i<=e-1;i++){
a[j]=b[i];
j++;
}
a[j]='\0';
printf("%s",b);
}
for eg: if the user enters 4 and 7, the output should be "king".
You appear to be trying to copy a portion of a to b, but in fact are assigning to elements of a.
You have your assignment in the loop backwards. Your a[] variable is the source string and b[] is the destination, but your assignment is a[j]=b[i]; which assigns b[i] to a[j]. This is a Really Good Example, by the way, of why variable names like a and b are bad. Had you used variable names like big_string and sub_string you wouldn't have had this problem. Similarly, names like i and j when you have multiple strings are confusing--big_index and sub_index or some such would be far more clear.
Stylistically, you would do better to keep i and j more closely parallel, instead of declaring and increment i on the for line, and declaring and incrementing j entirely differently:
int i, j;
for (i = s - 1, j = 0 ; i <= e - 1 ; i++, j++)
b[j] = a[i];
b[j] = '\0';
seems much cleaner to me.
Better yet, in my opinion, would be to use a single variable to track the number of chars processed, and use it as an offset to the original string and the index to the substring:
start--; // adjust user's input to start at 0 instead of 1
end--;
int dex;
for (dex = 0 ; dex <= end - start ; dex++)
sub_string[dex] = orig_string[start + dex];
sub_string[dex] = '\0';
(I also changed to more clear variable names, and shifted the correction for indexing from 1 to 0 to the variables instead of doing math inside the loop which just adds confusion).
And finally, the easiest way of all to do this is to use the built-in strncpy() function:
strncpy(sub_string, &orig_string[start], end - start + 1);
Just change the line
a[i] = b[j];
to b[j]=a[i];
and a[i] = '\0';
to b[j]='\0';
So I've got this here:
#include <stdio.h>
char halloString[] = "Ha::ll::o";
char perfumeString[] = "47::11";
char veryLongString[] = "47::11::GHesd::dghsr::bfdr:hfgd46dG";
char *extract (char *input) {somethinghappenshere}
where extract needs to get all characters after the last double ":" of given input:
"o" for halloString
"11" for perfumeString
"bfdr:hfgd46dG" for veryLongString
In short, my issue is finding the length of the string *input points to. As far as I understand it that won't be happening without making something really sketchy.
Am I correct in assuming the length cannot be acquired in a good way?
And if so would it be a horrible idea to do, for example:
char stringToProcessTemp1[50];
char stringToProcessTemp2[50];
char stringToProcess[50];
for (int i = 0; i < 50; i++) {
stringToProcessTemp1[i] = input + i;
}
for (int i = 0; i < 50; i++) {
stringToProcessTemp2[i] = input + i;
}
for (int i = 0; i < 50; i++) {
if (stringToProcessTemp1[i] == stringToProcessTemp2[i]) {
stringToProcessTemp[i] = stringToProcessTemp1[i];
}
}
Later checking where the first empty index is and saving everything before it as the used String as from my very limited experience in C when you go outside of an array you tend to get different outputs every time therefore making the chance both Temp strings match for an extra element directly after the last one of the original string what I'd consider low enough.
It's honestly the only idea I've got right now.
Finding the length of a string is no problem. strlen will do that for you. However, you don't even need that.
You can use the strstr function to find a substring within a string, in this case "::". When you find one, keep looking right after the last one you found until you don't find it anymore, then the last one you found is the one you want. Then you want the substring that starts right after it.
char *extract(char *input)
{
char *last = NULL, *start = input, *curr;
while ((curr == strstr(start, "::")) != NULL) {
last = curr; // keep track of the last "::" found
start = last + 1; // move the starting string to right after the last "::"
// move up 1 instead of 2 in case of ":::"
}
if (last != NULL) {
last +=2; // We found one; move just past the "::"
}
return last;
}
C strings, which are really only an array of characters, are by definition terminated by '\0'. So, for a well formed C string you can always get the length of the string by using strlen().
If, however, your string is not null-terminated, there is no way to determine it's length, and it is not a C string by definition any more, but just an array of characters.
I've searched around for a quiet some time but surprisingly I couldn't find an answer to it:
I want to rewrite a char array starting from [0], but all what's happening is: it's always appending. Here's my code:
The algorithm is: I have a very long string which I like to break into several lines (wherever there is a blank space at the end of a line). Each line shall be saved in an array Index (lineContent);
void print_text(char* content, int menu_width, int which_selected, int menu_height, int scroll_pos)
{
int posCounter = 0;
int charCounter = menu_width-10;
int printOutCounter;
char* lineContent[400]; // 400 lines max
short spaceFound;
while (strlen(content) > menu_width) // If string is longer than 1 line
{
//Interesting Part ---------- START
char changeString [strlen(content)];
char printString [menu_width-10];
spaceFound = 0;
charCounter = menu_width-10;
lineContent[posCounter] = malloc(MAXITEMSTR);
while (spaceFound == 0)
{
if (content[charCounter] == ' ')
{
// I guess the error goes between here ...
strncpy(changeString,content,strlen(content));
strncpy(printString,content,menu_width-10);
// ...and here
memmove(&changeString[0], &changeString[charCounter], strlen(content));
content=changeString;
lineContent[posCounter]=printString;
strcat(lineContent[posCounter],"\0");
posCounter++;
spaceFound = 1;
//Interesting Part ---------- END
}
charCounter--;
if (charCounter <= 0)
spaceFound = 1;
}
}
}
As I said, in the end, when checking the content of lineContent, every entry is the same (the one from the last line).
I think this is because, strcpy just appends to the end, therefor I have to clear the array, to erase the former line. So it will start from [0] and not from the last printed letter.
Has anybody an idea how to do this? Is there a function that overwrites a char array instead of appending it?
Kind Regards
Strcat appends to the end, strcpy overwrites the value stored in the string.
How to declare array of strings in C.
Is it like
char str[100][100] ={"this","that","those"};
If so how to access the values .. can i travers like this?
(It does not give any compilation error ..but shows some additional garbage characters)
int i ,j;
char c[100][100] = {"this","that"};
for(i = 0 ;c[i] != '\0';++i)
for(j = 0; c[i][j] != '\0';++j)
printf("%c",c[i][j]);
Is it necessary to add '\0' at end of eac string..for ex:
char c[100][100]={"this\0","that\0"}
How to declare array of strings in C
It is Ok, but you will have to be extremely careful of buffer-overflow when dealing with these strings
can i travers like this?
Note that the condition in the first for loop: for(i = 0 ;c[i] != '\0';++i) is probably wrong, and will fail since c[i] is an array, whose address is not 0. You should probably iterate the outer array by numbers [until you read all elements], and not until you find some specific character. You can do that by maintaining a different variable n, which will indicate how many elements does the array currently have.
Is it necessary to add '\0' at end of eac string..for ex:
No - the compiler add it to you, it is just fine without adding the '\0' to the string.
Yes, you can declare an array of strings that way.
No, you can't traverse it like that, the condition on your outer loop is bad - a string (char *) will never be equal to a character '\0'. The inner loop is fine.
No, you don't need to add the '\0', that will happen automatically.
c[i] is a pointer, so it has nothing to do with '\0'
so instead you should check c[i][0]
The compiler will add '\0' for you when you input a string like "this"
char str[100][100] ={"this","that","those"};
int main()
{
int i ,j;
char c[100][100] = {"this","that"};
for(i = 0 ;c[i][0] != '\0';++i)
{
for(j = 0; c[i][j] != '\0';++j)
printf("%c",c[i][j]);
}
}
So I have a string which will have the following rough format: string # more than one string here.
What I want to do is strip everything after the #. How would I do that? Furthermore, what if I just want to keep the initial string, and take everything after the space and the #?
I have the following code, but obviously appending something to a NULL string does not work as expected:
char *inst_ptr holds the whole string.
char *lbl = NULL;
int len = 0;
size_t inst_len = strlen(inst_ptr);
for (int t = 0; t < inst_len; t++) {
if (inst_ptr[t] == '#')
break;
else {
printf("len %d\n", len);
lbl[len] = inst_ptr[t];
lbl[len+1] = '\0';
len = strlen(lbl);
}
}
EDIT:
Basically, assume I have the following string:
loop # hello world!
I just want to extract loop in another string. What I am doing above is having lbl as a NULL string, and run a loop across the original string. As long as the character is not #, i just "append" the character with a null terminator as shown above.
Perhaps you should check section 7.21 in the standard for some inspiration.
The best approach depends on the rest of your application.
If you don't care about the original data, you could just use
strtok(inst_ptr, "#");
Or it might be better to allocate-and-copy just the data you need:
char * temp = strchr(inst_ptr, '#');
char * lbl;
if (temp)
lbl = strndup(inst_ptr, temp - inst_ptr);
else
lbl = strdup(inst_ptr);
Please note that the above are the minimal implemenations I've come to think of off the top of my head, not necessarily the best ones.
First, you are doing
char *lbl = NULL;
Then you are doing
lbl[len]
You're trying to dereference a NULL pointer and causing undefined behaviour.
First, you need to allocate memory for that string (calloc allocates the memory and sets it all to 0, which will obviate the need to manually add the null terminator):
char *lbl = calloc(inst_len + 1, 1);
Then you need to fix your loop, some of the things are in the wrong place. It should be
for (int t = 0; t < inst_len; t++) {
if (inst_ptr[t] == '#') {
len = t - 1; // strlen(lbl) is redundant
break;
} else
lbl[t] = inst_ptr[t];
}
Then when you are done, free the memory you allocated so as not to cause a memory leak:
free(lbl);