I would like to concatenate char array and the int array and store them in another char array. How could I do that?
Here is the code so far
char letter[100];
int number[100], i;
char * letterNum[100];
for (i = 0; i < 100; i++){
letterNum[i] = strcat(letter[i], number[i]);
}
expected output should be
a1 b1 ...
The strcat() function concatenates strings not chars, you need sprintf()
sprintf(letterNum[i], "%c%d", letter[i], number[i]);
and also, letterNum in your case is an array of pointers, it should be an array of arrays, like
char letterNum[100][3];
and then, you can use snprintf() instead of sprintf() to prevent buffer overflow
if (snprintf(letterNum[i], 3, "%c%d", letter[i], number[i]) > 2)
youHaveToDoSomethin_An_Error_Occurred();
I guess Mr. Iharob already answered your question, but just to elaborate a bit more,
Let's see the man page of strcat(). It says,
char *strcat(char *dest, const char *src);
which means it expects both the arguments to be pointer to strings. Now, as we know, a pointer to int array cannot be considered a string, we cannot use strcat() directly in your case.
So, what you have to do is,
Take another buffer
Copy both the contents of the char array and int array elements for particular index one after another in lexicographical format, so that the final result is the concatenation of both.
Now, you have sprintf()/ snprintf() to help you out in this case. It prints the formatted o/p to the supplied string.
A pseudo-code
char letter[100]; //populating value, not shown
int number[100]; //populating value, not shown
int i = 0;
char letterNum[100][32];
for (i = 0; i < 100; i++){
if ( sprintf(letterNum[i], "%c%d", letter[i], number[i]) != 2)
printf("Error in %d iteration\n", (i+1));
}
Thank you very much for your help!
I guess, I need to try an error and test it out myself... the explaination was clear and helpful... plus given codes for me to eeasily understand...
Your kind help is greatly aappreciated.. Thank you once again
Related
I know this code is quite simple; but that message won't stop appearing, can you help me find where the error is?
#include <stdio.h>
void Reverse(char * word[]) {
char temp = word[0];
for (int i = sizeof(word); i >= 0; i--){
for (int j = 0; j<= sizeof(word); j ++){
word[0] = word[i];
}
}
word[sizeof(word)] = temp;
printf("%s", word);
}
void main() {
Reverse(gets(stdin));
return 0;
}
gets returns char*. In this context - It is wrong to write char *[] in the function definition where you are supposedly passing a char array where input characters are being stored using gets. Also char *gets(char *str) - you need to pass a buffer to the gets where the inputted letters will be stored. You didn't pass one.
sizeof doesn't work here. It returns the size of a pointer (char*). You will have to use strlen() to get the length of the string inputted by gets.
More importantly - don't use gets - it's time to use something much safer than gets, namely fgets etc. Buffer overflow is not something you want to deal with.
Suppose you are passing an array of char* to the function reverse. Then the parameter would be char*[] which means nothing other than char** here. Here you will simply pass the char array which you will be using as buffer to gets.
I need to read an array of n strings from 2 letters in each (e.g. n = 3, need to read something near "ab bf cs"). I use this code and get segmentation fault:
int n;
scanf("%d", &n);
char array[n][2];
char *tmp;
for (int i = 0; i < n; i++)
{
scanf("%s", &tmp);
strcpy(array[i], tmp);
}
Please help me to fix it!
Problem 1
To store a string of length 2, you need a char array of size 3. Use:
char array[n][3];
Problem 2
You are using &tmp in the call to scanf. That is wrong on two accounts.
The type is not appropriate. Type of &tmp is char**. scanf needs a char* with the %s format specifier.
&tmp cannot hold a string.
You could use
scanf("%s", tmp);
That will be OK from type point of view but it won't ok from run time point of view since tmp does not point to anything valid.
You can do away with tmp altogether and use:
scanf("%s", array[i]);
That entire block of code can be:
int n;
scanf("%d", &n);
char array[n][3];
for (int i = 0; i < n; i++)
{
// Make sure you don't read more than 2 chars.
scanf("%2s", array[i]);
}
There are a couple things you need to fix here.
Remember that one "string" (char[]) always ends with a null terminating character \0. So, whenever you create a char[], you must leave enough space for that. For example:
char str[3] = "foo"; looks like ['f', 'o', 'o'], but
char str[4] = "foo"; looks like ['f', 'o', 'o', '\0'].
Unexpected consequences can occur when using the former.
This means that you should change char array[n][2] to char array[n][3].
Remember that pointers are different than arrays. If you want to use a pointer, you must allocate memory for it, otherwise you will most likely seg fault.
In your program, it's simple enough that you can probably get away with not using a pointer, especially since you know the the length of each string that you will be storing (2).
You could change char *tmp to char tmp[3].
You can actually refactor your code so you don't need the tmp variable at all. If you want, you can just store the word you read into the array directly. For example:
scanf("%s", array[n]);
If you are really insistent on using that tmp variable as a char *, then allocate memory for it, like so:
char *tmp = (char*)malloc(3 * sizeof(char));
As a sidenote, if you are adhering to the ISO C90 standards, you shouldn't intermix variable declarations in code, so in your loop where you have for(int i = 0...), you should declare int i; at the top of the file, and then assign it in the loop for(i = 0...).
First, as user3121023 pointed out in the comments, char *tmp; creates a pointer without memory allocated to it. scanf() needs an array, and you need space for the terminating '\0' (which is probably the source of your segmentation fault). So you could try scanf("%s", array[i]);.
Second, it's a good idea to use "%2s" instead of "%s" so the user doesn't input 3 digits and overflow your buffer.
Here's one solution.
int n;
scanf("%d", &n);
char array[n][3];
for (int i = 0; i < n; i++)
{
scanf("%2s", array[i]);
}
I have an assignment I've been working on for a few hours now, and I can't seem to get it quite right. The assignment is to take a random number of names (from stdin), sort them, and then output them in alphabetical order. I can't find any sites online that handle this kind of sorting specifically, and have had no luck trying to implement qsort() into my code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int stringcmp(const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp(*ia, *ib);
}
void main(int argc, char *argv[])
{
char *input[] = {" "};
char temp[20][20];
int i = 0;
int num = 0;
int place = 0;
int stringlen = sizeof(temp) / sizeof(char);
printf("How many names would you like to enter? ");
scanf("%d", &num);
while (place < num)
{
printf("Please input a name(first only): ");
scanf("%s", input[place]);
printf("The name you entered is: ");
printf("%s\n", input[place]);
place++;
}
//qsort(temp, stringlen, sizeof(char *), stringcmp); <-- just an idea I was messing with
qsort(input, stringlen, sizeof(char *), stringcmp);
printf("Names:\n");
for(i=0; i<place; i++)
printf("%s\n", input[i]);
system("PAUSE");
return(EXIT_SUCCESS);
}
The main problem is, when I go to output my code, I cannot use the char *input variable because of how its declared. The temp[] will display, but will not be sorted by qsort because it is not declared as a pointer. Any ideas?
You can't declare your input array like that. Since you know how many the user requires, you can dynamically allocate the array:
char **input = malloc(num * sizeof(char*));
Likewise, when you read your strings in, they need somewhere to go. Simply passing an uninitialized pointer to scanf is not okay. I suggest you define the maximum length of a name and have a temporary buffer for reading it:
const size_t MAX_NAME = 50;
char name[MAX_NAME];
...
for( i = 0; i < num; i++ )
{
printf("Please input a name(first only): ");
scanf("%s", name);
input[i] = strdup(name);
}
[Note this does not prevent the user from overflowing the 'name' buffer. I used scanf for illustrative purposes only]
You seem to be passing the wrong array length to qsort. Try this:
qsort(input, num, sizeof(char *), stringcmp);
When you are finished, you need to release memory for all the names and the array.
for( i = 0; i < num; i++ ) free(input[i]);
free(input);
could you explain
the ** declarations throughout the code? I'm not sure what they're
used for, although I know the function for stringcmp is a widely used
algorithm, I have no idea how it works; I'm thrown off by the double
de-reference markers.
Yep, in the case where I used it, I am telling C that to get a single character, I have to dereference a pointer twice. When you index a pointer, it's dereferencing. So I allocated an array by requesting a block of memory containing num * sizeof(char*) bytes. Because I assigned that pointer to a char**, the compiler knows that I am pointing to a chunk of memory that contains char* values.
If I ask for input[0] (this is the same as *input) it should look at the very start of that memory and pull out enough bytes to form a char*. When I ask for input[1], it skips past those bytes and pulls out the next bunch of bytes that form a char*. Etc... Likewise, when I index a char*, I am pulling out single characters.
In your stringcmp function, you have the following situation. You passed a void* pointer to qsort so it doesn't actually know the size of the data values stored in your array. That's why you have to pass both the array length AND the size of a single element. So qsort just blindly rips through this arbitrary-length array of arbitrary-sized values and fires off memory addresses that ought to contain your data for comparison. Because qsort doesn't know anything else about your array elements except where they are located, it just uses void*.
But YOU know that those pointers are going to be the memory addresses of two of your array elements, and that your array elements are char*. So you need the address of a char* (hence you cast the pointers to char**). Now you need to dereference these pointers when you call strcmp() because that function requires a char* (ie a value that points directly to the memory containing your string characters). That is why you use the * in strcmp(*ia, *ib).
One quick way to fix your program is to declare input as an array of pointers, like this:
char *input[20];
When you read names in, use tmp[place] for your buffer, and store the pointer into input, like this:
scanf("%19s", tmp[place]);
input[place] = tmp[place];
Now sorting the input should work fine.
This has a limitation of being limited to 20 lines of 20 characters max. If you learned about malloc in the class, you should be able to fix that by allocating your strings and the string array dynamically.
I know this question might sound quite silly, but I somehow found myself stuck and need help. I have a char* variable char* address="/a/asdasd/c/sdfsdf/adsd"; and I declared an array of char pointer char* store[5]; . I'm trying to divide the content in the variable address by tracing the slash(/) and trying to store each part in the char pointer variable store by doing the following
char* store[5];
char* address="/a/asdasd/c/sdfsdf/adsd";
int k=0;
int j=0;
char* b=NULL;
for(int i=0;i<5;i++)
{
if(b==0)
{
b=strchr(address,'/');
}
else
{
b=strchr(b,'/');
}
j=b-address;
strncpy(store[i],address+k,j-k);
k=j;
}
But I see that in the code strncpy(store[i],address+k,j-k) there's an error. The compiler doesn't seem to understand that store[i] is a char pointer, it rather thinks it is a char. Could you see how I can solve the problem?
Thanks for all the help. I've solved it. Solution code is as below:
char* address="/a/asdasd/c/sdfsdf/adsd/asfsd";
char store[5][100];
char* b=NULL;
int k=0;
int j=0;
for(int i=0;i<5;i++)
{
if(b==0)
{
b=strchr(address+1,'/');
}
else
{
b=strchr(b+1,'/');
}
j=strlen(address)-strlen(b);
strncpy(store[i],address+k+1,j-k-1);
store[i][j-k-1]='\0';
printf("%s\n",store[i],j-k);
k=j;
}
char *store[5]
This is just an array of char pointers. To store strings in each element of this array, you need malloc memory and assign it to the respective pointer.
For Ex, you can change your code to
store[i] = malloc ((j-k)+ 1); // +1 is for the null terminator. Pls check return value of malloc also.
strncpy(store[i],address+k,j-k);
If you want to copy a pointer, you shouldn't be calling strncpy(), since that copies characters.
You want:
store[i] = address + (j - k);
assuming address + (j - k) is the desired starting point for the part.
If you don't want to have a copy of the string tokens, if you like only to retain the pointers, then just store the address in store[i] as #unwind pointed out. Or else, you could explore strtok () also. only think is that you need to have separate array to keep each length of the string according to your code. Hope this helps.
I have a doubt in my program
#include<stdio.h>
int myFunc(char **);
main()
{
char *a[2]={"Do","While"};
myFunc(a);
}
int myFunc(char **P)
{
/* Here I want to print the strings passed but I'm unable to
print the strings I just tried the below statement which
printed just the first letter which is 'D'*/
printf("%c",**P);
}
when i tried
printf("%s",**P);
I am getting run time error. so can anyone please help me out?
Thanks
Madhu
Put size as parameter to allow the function to know how many strings you have in your array. Then, you should iterate the array and print each one.
int myFunc( char** p, int size)
{
for( int i = 0; i < size; ++i)
{
printf("%s", p[i]);
}
}
Later edit (as requested :-) )
int main( int, char**)
{
char *a[2]={"Do","While"};
myFunc( a, 2); // Could be myFunc( a, sizeof(a)/sizeof(char*));
// ...
return 0;
}
Too many stars - try
printf("%s",*P);
And you need %s format specifier - %c is just for single character.
If you want to print all strings, you need to pass number of strings in array and then print these strings from the loop.
Check the code suggested by Cătălin Pitiș. To pass the number of strings, you call function like this:
myFunc(a, sizeof(a)/sizeof(a[0]));
for( int i = 0; i < 2; i++ ) {
char* string = P[i];
printf( "%s", string );
}
And you shoud use some way of passing size of array into the function - either pass it as an int parameter,
int myFunc(char **P, int size)
{
for( int i = 0; i < size; i++ ) {
//whatever here
}
}
or always append a zero value to the array and only loop until you find that zero value.
char* array[] = { "String1", "String2", 0 };
Otherwise you will have hard to maintain code.
I like objective-c style nil (0) terminated arrays:
void myFunc(char **P)
{
while (*P) // loop to iterate over all strings until 0
printf("%s\n",*P++); // print and move to next element in array
}
int main()
{
char *a[]={"Do","While",0}; // added 0 to null terminate array,
myFunc(a); // kind of like string
}
Output:
Do
While
First, the good news: the type of a is equivalent to char **, so you are passing a valid parameter to myFunc().
The first problem is that %c is a format specifier that means print a single character. Since **P is an expression that evaluates to a single character, your first version does exactly what you told it to do. That isn't what you want.
The second version is close to syntactically correct. It should read printf("%s", *P), where *P is an expression that evaluates to a pointer to a nul-terminated ASCII string. In this case, it evaluates to "Do". This version won't print both strings.
Although it is true that the name of an array is the same as a pointer to its first element, that is a kind of "lie to students". Passing an array to a function does not and cannot convey the length of the array. To do that, you need either a second argument containing the length, or a convention like the nul-terminator on a string to indicate the end of the array. With that change, you can modify myFunc() to use a loop over the elements passed and print each one.
The problem in your code is that you want to print a string (char*) but you're giving it a char. Remember that P is an array of char*. When you de-reference it once, you get a char*; when you do it a second time, you just get the char at the beginning of the char*.
When you try to use the char value with the %s specifier, it treats the value as a pointer, and tries to dereference that value. Hence, it will try to print the "string" at the memory location X, where X is the value of the char (i.e. a value from 0 to 255). This gives you an access violation/segmentation fault (the error you see at runtime).
The best workarounds for this, as noted by Cătălin Pitiș and RBerteig, are to either:
pass another parameter to specify the length of the array
add an additional null at the end of the array.
if you don't want to keep and pass around array size::
int myFunc(char **);
main()
{
char *a[2]={"Do","While", NULL};
myFunc(a);
}
int myFunc(char **P)
{
if( !P )
return 0;
while(*P != NULL)
{
printf("%s",*P);
P++;
}
}
Wrong Answer: I think you may have to dereference P when you print it, although I could be wrong.
EDIT: I'm tired, it's 3 am here but I don't feel like sleeping so I'm here trying to answer questions. After reading the criticism, I reread the question and noticed that he does dereference P, but as is stated in another answer, it's dereferenced too much. When one wants to print a char string, one wants to pass a pointer as the char string is really an array.
Another EDIT: I would also like to point out that the person who asked the question made an edit after I answered and that when I first answered it didn't read "printf("%s",**P);" it read "printf("%s", P);" and the last part was bold.