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]);
}
}
Related
I just started learning C language and I need some help with a program. Here is the code.
Questions:
What is this? customerData[NUM_FIELDS][FIELD_LENGTH];
Is it a char 2D array?
How do you input data into the array? fgetC, putchar, getchar ?
#include <stdio.h> #include <string.h> #include <stdlib.h>
#define INPUT_LENGTH 128
#define FIELD_LENGTH 30
#define NUM_FIELDS 9
int main()
{
FILE *data=NULL;
char input[INPUT_LENGTH];
char customerData[NUM_FIELDS][FIELD_LENGTH];
int element=0;
char *next;
char ch;
data= fopen("data.txt","r");
if(data!=NULL)
{
//token=strtok(input,"|");
/*while loop will go through line by line and stored it in an input array*/
while(fgets(input,INPUT_LENGTH,data)!= NULL)
{
next=strtok(input,"|");
while(next!=NULL)
{
//ch=getchar()
//>probably a get char for ch
strcpy(next,customerData[element][strlen(next)]);
/*need to put the values into customer data one by one*/
printf("%s\n",next);
//element+=1;
next=strtok(NULL,"|");
}
//element=0;
}
printf("program is done\n");
}
fclose(data);
return 0;
}
In general, "help me with my code" questions are off-topic on Stack Overflow. In order to keep the question on-topic, I'm going to focus only on the question of how to access 2D char arrays.
Yes, this is a 2D char array. Or, put another way, it's an array with NUM_FIELDS elements, where each element of the array is a char array with FIELD_LENGTH elements.
There are loads of ways to insert data into a 2D char array, but there are probably two I've encountered most often. Which one you choose to use will depend on how you want to think of this array.
Option 1: A 2D array of single chars
The first way to think about this variable is simply as a 2D array of chars - a grid of elements that you can access. Here, you can simply input values using the normal assignment operator. You'll want to make sure that your indexes are in range, or you'll start accessing invalid memory.
//Set a known element that's definitely in range
customerData[1][2] = 'A';
//Loop through all the elements
for(int ii = 0; ii < NUM_FIELDS; ii++)
{
for (int jj = 0; jj < FIELD_LENGTH; jj++)
{
customerData[i][j] = 'B';
}
}
//Set an element from variables
char nextInput = getNextCharFromInput();
if(x < NUM_FIELD && y < FIELD_LENGTH)
{
customerData[x][y] = nextInput;
}
//Bad. This could corrupt memory
customerData[100][60] = 'X';
//Risky without check. How do you know x and y are in range?
cusomterData[x][y] = 'X';
You could certainly write your code by assigning these elements on character at a time. However, the broader context of your program heavily implies to me that the next option is better.
Option 2: A 1D array of fixed-length strings
In C, a "string" is simply an array of chars. So another way to look at this variable (and the one that makes the most sense for this program) is to treat it as a 1D array of length NUM_FIELDS, where each element is a string of length FIELD_LENGTH.
Looking at this this way, you can start using the C string functions to input data into the array, rather than needing to deal character by character. As before, you still need to be careful of lengths so that you don't go off the end of the strings.
Also be aware that all array decay into pointers, so char* is also a string (just of unknown length).
//Set a specific field to a known string, which is short enough to fit
strcpy(customerData[2], "date");
//Loop through all fields and wipe their data
for(int ii = 0; ii < NUM_FIELDS; ii++)
{
memset(customerData[ii], 0, FIELD_LENGTH);
}
//Set field based on variables
if(x < NUM_FIELDS)
{
//Will truncate next if it is too long
strncpy(customerData[x], next, FIELD_LENGTH);
//Will not input anything if field is too long
if(strlen(next) < FIELD_LENGTH)
{
strcpy(customerData[x], next);
}
}
//Bad. Could corrupt memory
strcpy(customerData[100], "date");
strcpy(customerData[1], "this string is definitely much longer than FIELD_LENGTH");
//Risky. Without a check, how do you know either variable in in range?
strcpy(customerData[x], next);
getchar and fgetC both deal with reading characters, from stdout and a file respectively, so can't be used to put data into a variable. putchar does deal with put character into things, but only stdout, so can't be used here.
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';
Using a global variable like:
params_vector[100][100] = {};
Is it possible to 'reset' or 'clear' the values inside this array just to be equal as from when it's initialized? There are a lot of examples with char *arg[] (which arg[i] = NULL works) but none with a 'matrix' like this.
If this is a multidimensional array of char, you can "reset" it simply by calling
#include <string.h>
memset(params_vector, 0, sizeof params_vector);
If you just need to set the first byte of each string to 0, using a for loop could be more efficient.
Assuming this is a multidimensional array of char's, e.g.
char params_vector[N][M];
for some value of N and M - you don't need to memset() the entire thing to '\0'; it's enough to set the first character of each string to '\0':
for(size_t i = 0; i < N; i++) {
params_vector[i][0] = '\0';
}
However, if N is small, this optimization might not be worth it and a
memset(params_vector, '\0', M * N);
would be fine.
Use memset:
memset(params_vector, 0, sizeof(params_vector));
I have a date type defined as
typedef char* DateTime;
the format is "dd/mm/yyyy-hh:mm" e.g. "08/08/2012-12:00"
and I want to allocate n string that are "dates".
What is wrong with the following?
DateTime* dates = (DateTime* ) malloc(sizeof(char*) * n);
for (int i = 0; i <= n; i++) {
dates[i] = malloc(sizeof(char)*16);
if (dates[i] == NULL) {
free(dates);
return NULL;
}
}
for (int i = 0; i <= n; i++) {
^
In C arrays start from 0 so dates[n] cannot be accessed. Drop the =.
Besides responses by #Dan and #cnicutar (both of which are spot on), note that the string literal "08/08/2012-12:00" contains 17 characters (not 16). While it's string length is 16, it contains the 16 characters that you see PLUS the '\0' character at the end that serves as the terminator. Also, sizeof(char) is one by definition. Finally, the idiomatic way to allocate memory using malloc would be -
DateTime *dates = malloc(n * sizeof *dates);
In addition to cnicutar's answer there is also this:
In the event that this condition is true:
if ( dates[i] == NULL )
you are only calling free on the overall array, and not freeing the elements before i in the array. This can lead to a significant memory leak
As been pointed out be both me in a comment, and by others, the loop
for (int i = 0; i <= n; i++) {
is looping once to many.
Another problem is this:
dates[i] = malloc(sizeof(char)*16);
The actual string is 16 characters, but since strings in C needs an extra terminator character ('\0') you need to allocate one character more, which means you should multiply by 17.
And as noted by Dan F you also have a potential memory leak.
The two biggest problems is the looping and allocation, as that will cause so called undefined behavior when overwriting unallocated memory.
I am trying to count the number of elements in an array using C. I tried out the following code. But it just returns 83 every time I run the program. What I mean by to count the number of elements is that I need to know the number of elements that we have entered and not the size of the array.
#include<stdio.h>
#include<stdlib.h>
main(){
int a[100], j = 0, i;
a[0] = '0';
a[1] = '1';
a[2] = '2';
a[3] = '3';
a[4] = '4';
a[5] = '5';
for(i=0; i<100; i++){
if(a[i] == '\0'){
}
else
j = j + 1;
}
printf("%d", j);
system("pause");
}
Arrays in C are a fixed size. They do not expand. Your array has two entries; writing to array[2], array[3], etc. invokes undefined behaviour. In other words, it's invalid code.
If you want to be able to insert an arbitrary number of elements, you will need to use dynamically-allocated memory, manually track how many elements you've inserted, and use realloc when you need to resize.
Since the OP amended his code, here is a more correct reply:
This code works 'by chance', since you didn't initialize the array previously.
It's just 'luck', that somewhere in there, the value 0 comes up.
The declaration of an array does NOT zero it.
Use:
memset(a, 0, 100);
For that. That way, the first 'not overwritten' byte will return '0'.
Reference: http://www.cplusplus.com/reference/clibrary/cstring/memset/
Alternatively, you have to set the 'delimited' manually by adding a[x] = 0;
Now, I know you specifically asked for a 'C' solution, but if you would like to consider using a C++-Compiler, I suggest looking at the stl of C++.
Here's a link to get you started: http://www.cplusplus.com/reference/stl/list/
It's initialized as:
list<char>List;
List.push_back(1);
List.push_back(2);
List.push_back('a');
int j = List.size(); //Returns '3'
do this instead:
main(){
int a[100] = {0};
int j = 0;
int i = 0;
// other stuff
Update based on new code:
In general, you will need a way to identify the end of your array in order to do a correct count. For strings the '\0' is used generally. For other data types you have to come up with your own value to check.
For your specific code example above:
You need to insert a \0 yourself into your array in the last position so that your count will work. (When you create a string like "hello", the '\0' gets automatically put in for you at the end of the string, but not if you create a string character by character).
Alternatively, check for the character '5' to find the end of your current array of characters.
Also, you should break out of the loop once you found the last character, otherwise you are going past the end of the array and will most likely crash (again, if you don't it's sheer luck). I.e., something like:
if(a[i] == '\0'){
break;
}
will work if you do:
a[6] = '\0';
before.
Since C doesn't check array bounds, it might appear that with your current code you seemingly get away with this, but it's sheer luck that the program doesn't crash and may change from run to run. In other words, this is undefined behavior.
Finally, you can of course also use strlen() if you are dealing with strings.