How would i get the lengths of the belowed strings, as well as the array size?
char str [] = {};
str[0] = "He";
str[1] = "llo";
str[2] = " Wor";
str[3] ="ld";
And how i could store them in a multidimension array? So this array would look something like this:
char strstr [size of str][string length of str];
The strstr[][] array-dimensions should be
1.number of array-elements of str and
2.number of all chars in str. In the case of strstr[3][1], this would be "d".
Would that be possible without initializing the str-array in the first place?
[edit]
I see, the second dimension of strstr doesn't make sense. It should be the length of every element from *str and not the complete number of chars in *str
[/edit]
This will probably do what you want, but it wasn't exactly what you asked for.
#include <stdio.h>
char *strs[] = {
"foo",
"bar",
"bazy"
};
int main() {
printf("%d - %s\n", strlen(strs[0]), strs[0]);
printf("%d - %s\n", strlen(strs[1]), strs[1]);
printf("%d - %s\n", strlen(strs[2]), strs[2]);
return 0;
}
Output:
3 - foo
3 - bar
4 - bazy
Note that you only have a few possibilities for storing arrays of arrays. You can either do what this solution does (make an array of pointers to arrays), make a "compressed" list of arrays in a large array, or make an overly large 2-D array.
The "compressed" array would take the format:
char strs[] = "foo\0bar\0bazy"; // array is {f,o,o,\0,b,a,r,\0,b,a,z,y,\0}
The problem with this format is that it's somewhat tricky to access anything after the first element, and usually involves searching linearly through the array. (or keeping a seperate table of addresses... rather like the first solution)
The 2-D array requires that you specify all sizes, and looks like this:
char strs[3][5] = {
"foo",
"baz",
"baxy"
};
int main() {
printf("%d - %s\n", strlen(strs[0]), strs[0]);
printf("%d - %s\n", strlen(strs[1]), strs[1]);
printf("%d - %s\n", strlen(strs[2]), strs[2]);
return 0;
}
This is probably laid out in memory like this:
{f,o,o,\0,*,b,a,z,\0,*,b,a,x,y,\0} (the *'s could be anything, most dependent on your compiler)
Since the compiler knows that each string takes exactly 5 bytes, it can easily calculate the location of the later elements.
When declaring an array in C, you must declare its size unless you are simultaneously providing initializing values. This is because arrays are laid out sequentially in memory, and so the computer needs to know how much space to set aside.
Further, char str [] = {....} will declare an array of characters, not an array of strings. A string is an array of characters, so str is just a single string.
To create an array of strings, you need to do something like this:
char strs[num_of_strings][max_length_of_strings+1];
strcpy(strs[0],"string1");
strcpy(strs[1],"string2");
...
There's a more in depth discussion of other options at this question.
If you're specifying max_length_of_strings but then copying from source strings that you can't guarantee are shorter than max_length_of_strings, you want to use strncpy instead of strcpy. In that case you also want to ensure that the resulting strings are null terminated, which you can do by looping
strs[i][max_length_of_strings] = '\0';
To get the length of a null-terminated string, you use the function strlen.
As to the second part of your question, the above should make it clear how to create a higher-dimensional array. I'd provide more detail, but I'm not exactly sure what you want this array to do. When you say "number of all chars in str" do you mean the max length of the strings stored in your strs array?
If so, you don't need to worry about that. Programming your strs array like I explained it above will already give you this functionality: since strings are just arrays of char's, you can index into strings in the same way that you index into char's.
Let me know if any of the above isn't clear, and I'll try to explain it better.
If you want an actual array, something like this:
char str[4][5]; // holds up to 4 characters in each
strcpy(str[0], "He");
strcpy(str[1], "llo");
strcpy(str[2], " Wor");
strcpy(str[3], "ld");
To get the length of a string in C you'd use strlen and pass the string.
int len = strlen(array[0]);
Related
Newbie to programming (school) and I'm a little confused on what/why this is happening.
I have a loop that is iterating over an array of elements, for each element I am taking the integer of the array, converting it to a char using the function getelementsymbol, and using strcat to append to my temp array. The problem I am having is that the elements of my temp array contain the residual of the element proceeding it. This is the snippet of my code. The output I receive is this:
word1
word1word2
word1word2word3
char* elementsBuildWord(const int symbols[], int nbSymbols){
/* ROLE takes a list of elements' atomic numbers and allocate a new string made
of the symbols of each of these elements
PARAMETERS symbols an array of nbSymbols int which each represent the atomic number
of an element
nbSymbols symbols array's size
RETURN VALUE NULL if the array is of size <= 0
or if one of the symbols is not found by our getElementSymbol function
other the address of a newly allocated string representing the concatenation
of the names of all symbols
*/
char s1[MAX_GENERATED_WORD_LENGTH];
int y;
char *s2;
size_t i;
for (i = 0; i < nbSymbols; i++){
y = symbols[i];
s2 = getElementSymbol(y);
strcat(s1, s2);
}
printf("%s ", s1);
}
Firstly, your s1 is not initialized. strcat function append a new string to an existing string. This means that your s1 has to be a string from the very beginning. An uninitialized char array is not a string. A good idea would be to declare your s1 as
char s1[MAX_GENERATED_WORD_LENGTH] = { 0 };
or at least do
s1[0] = '\0';
before starting your cycle.
Secondly, your getElementSymbol function returns a char * pointer. Where does that pointer point to? Who manages the memory it points to? This is non-obvious from your code. It is possible that the function returns an invalid pointer (like a pointer to a local buffer), which is why might see various anomalies. There's no way to say without seeing how it is implemented.
strcat is supposed to append to a string. use strcpy if you want to overwrite the existing string. You could also use s1[0] = '\0'; before strcat to "blank" the string if you really want to, but looks like you really want strcpy.
From the snippet above it's not even clear why you need s1 - you could just print s2...
I am under the impression that on each run, in my Strings array, I am storing at pos a new str since I am declaring it everytime, instead, on the 2nd run if addstr become hello, and on the first run It was hi, the first run hi also becomes hello. I just want a different char array on each run in Strings so later on each position I have a different strings. The requirements is that I can not use malloc, realloc, calloc. I really thought that on the 2nd iteration of the first for loop I am creating on a char str independent of the previous one. Please help me.
int pos = 0;
for(i=0; i<4; i++)
{
if(file [i]=='a')
{
char str[5];
int b=0;
for(b; b<3; bi++)
{
str[b]=file[b];
}
Strings[pos]=str;
pos++;
}
}
When you do this:
Strings[pos]=str;
It merely sets that array element to the buffer pointed to by 'str'. It does not copy the string. The 'str' buffer never changes, so your entire array ends up pointing to the same buffer.
Rather, at that line you need to copy the string. If you can't use malloc, then your Strings array needs to have buffers at each array element (aka 2 dimensional array). Maybe declare it something like:
char Strings[5][5];
Then instead of using your strcpy to copy to 'str', copy the string to 'Strings[pos]';
I was wanting to create a 2 dimensional string array that had dimensions "string[5][*]" but was having some trouble. I would like to do something like this:
...
for(i = 0;i < 5;i++){
char* word = ...;
if(strcmp(word,...)){
string[i][j] = (char *) malloc(/*size of word*/);
string[i][j] = word;
j++;
}
}
The "string" variable should be of length 5 in the ith direction and should be allowed to grow as much as I need in the jth direction.
I tried doing:
char* string[5];
but that does not seem to work. Please note the above for loop has been simplified and parts might not seem logical.
EDIT:
I am trying to sort a list of strings into 5 categories. So the n-dimentional array should in a sense hold 5 arrays containing an unspecified number of strings (not chars). This I assume is a 3-dimentional char array but was having trouble thinking of how to write it. I want every string[i][j] term to hold a char array. So string[0][0] could equal "cat" or something.
Try this.
char **string;
string = (char **)(malloc(sizeof(char *) * 5));
//malloc the string[i] whenever you need to at what ever size is necessary.
Also in your code at the top the problem is each string[i][j] is a char and you can't malloc for a non pointer. Every string[i] is a char * you have to malloc for that.
This line
string[i][j] = ...
would doubly dereference a char**, which means you're assigning something to a char. If that something happens to be a pointer, then the compiler won't allow it.
Instead, I think you want:
string[i] = (char*) malloc(...);
And then your 2D array definition remains as you had tried it:
char* string[5];
You may already know this, but I'll add a few other notes just in case. C strings generally can't be assigned using =. Instead, you need:
strcpy(string[i], word);
Secondly, the malloc() shouldn't be strlen(word) but rather:
strlen(word) + 1
The extra byte is for the nul terminator.
I'm not used to C as I'm primarily a Java guy, with some knowledge of C++, so forgive me if this is a trivial question. I could not seem to find an answer while searching online.
I'm initializing a char array...
char tcp[50];
So that I can concatenate a const char and a char. In examples I saw an easy way to do this was by creating that empty char array and then using...
strcat(x,y);
To stick them together.
Problem is, printing out the blank char array when it is set to "50" gives me a result of:
X??|?
When I change it to...
char tcp[100];
And print it, its blank. Why is this?
The array contents are undefined, assuming it is a local (automatic) array.
Use:
char tcp[50] = "";
Or:
char tcp[50] = {0};
Or:
char tcp[50];
tcp[0] = 0;
Or:
char tcp[50];
memset(tcp, 0, sizeof(tcp));
As you like.
Always null terminate you char arrays before doing anything:
tcp[0] = '\0';
C happily allocates the space for the array you declare, but it does not set its content to 0.
Therefore, the content of the array you're printing is random (or rather depending in the previous contents of the memory)
When creating an array, the compiler puts it somewhere in memory but does not initialize it, so whatever is in that memory when the program is started will be the initial "string".
Terminate the string manually after you created the array, either by making the whole array "zeroed" out, or just put zero as the first character:
char tcp[50] = { '\0' };
Or
char tcp[50];
/* ... */
tcp[0] = '\0';
The difference here is, you're essentially working with two empty arrays trying to merge them in the memory space of one (not sure if that makes sense for you).
First of all, in C you have to terminate strings with \0. That's something not exposed or visible in Java. Also you essentially used two undefined strings (as there's no value set).
#include <stdio.h>
#include <string.h>
char target[256];
const char source_a[] = "Hello";
const char source_b[] = "World!";
int void(main)
{
target[0] = '\0'; // this essentially empties the string as we set the first entry to be the end. Depending on your language version of C, you might as well write "char target[256] = {'\0'};" above.
strcat(target, source_a); // append the first string/char array
strcat(target, " "); // append a const string literal
strcat(target, source_b); // append the second string
printf("%s\n", target);
return 0;
}
Important: Using strcat() can be unsave, as there's no length check performed, and other than Java, these "strings" have a fixed length (the one you set when defining the variables). If there's no length given, but you copy a string on initialization, that length is taken (e.g. char test[] = "Hello!"; will be 7 chars long (due to terminating \0)).
If you'd like a more Java like approach on strings, use C++ and the std::string class, that performs a lot more similar to Java's strings.
I am trying to copy certain parts of a string into other, new strings, but when i try to do it and print the results it gives me weird output.. I really hope someone can help. I have a feeling that it is something about missing pointers.. Here is my source;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void getData(char code[], char ware[], char prod[], char qual[])
{
printf("Bar code: %s\n", code);
/* Copy warehouse name from barcode */
strncpy(ware, &code[0], 3);
ware[4] = "\0";
strncpy(prod, &code[3], 4);
prod[5] = "\0";
strncpy(qual, &code[7], 3);
qual[4] = "\0";
}
int main(){
/* allocate and initialize strings */
char barcode[] = "ATL1203S14";
char warehouse[4];
char product[5];
char qualifier[4];
getData(&barcode, &warehouse, &product, &qualifier);
/* print it */
printf("Warehouse: %s\nID: %s\nQualifier: %s", warehouse, product, qualifier);
return 0;
}
EDIT:
The wierd output is:
Bar code: ATL1203S14
Warehouse: ATL
ID: ♫203(♫>
Qualifier: S14u♫203(♫>
I think you meant '\0' instead of "\0" and 3 instead of 4:
ware[4] = "\0";
Try:
ware[3] = 0;
Also the & in getData(&barcode, &warehouse...) are useless. Just use getData(barcode, warehouse...);.
You're writing past the end of the chars in your getData() function. You've defined char product[5], which allocates 5 bytes of memory. That gives you array indexes 0,1,2,3,4. In getData, you write the product's null terminator to index 5, which is past the end of product, and will overwrite the next var's first character.
The same applies for barecode, warehouse, and qualifier.
Arrays in C and C++ are zero-based. The last index is one less than the length. You're setting a value in the memory after the array, for each of the arrays ware, prod and qual.
For example, instead of
char warehouse[4];
ware[4] = "\0";
you'd want:
char warehouse[4];
ware[3] = "\0";
getData(&barcode, &warehouse, &product, &qualifier);
This is not the way you should call getData. getData takes pointers, arrays are automatically converted to pointers, so theres no need to use the address-of operator &.
You should use
getData(barcode, warehouse, product, qualifier);
The sizes of the strings inside main() don't include a place for the sentinel.
You need to have:
char warehouse[5];
char product[6];
char qualifier[5];
Also, You are assigning a pointer to the string "\0" into a character, where you should be assigning the character '\0' itself.
I think I'd do things a bit differently. In particular, strncpy is almost never really useful (I'm reasonably certain it was invented for file names in the original Unix FS, and while it fits their specific requirements quite nicely, those requirements are sufficiently unusual that it's rarely good for much of anything else).
Instead, I'd use sscanf: sscanf(code, "%4c%5c%4c", ware, prod, qual);
Your question does not make it clear whether this is really correct. As others have pointed out, you're writing past the ends of the space you've allocated. Above, I've assumed you specified the number of characters you want to copy, so you'd have to expand each of the allocations by one character to make room for the terminator. Alternative, if you've already left room for the terminator and want one fewer character copied, you'd have to reduce each of the lengths above by one so the format string would be "%3c%4c%3c".