possible way to implement array of pointers to string - c

I had a code which works fine with the integers
#include<stdio.h>
int main()
{
int i;
int* p[5];
printf("Enter the elements to be shorted");
for(i=0;i<=4;i++)
{
scanf("%d\n",&p[i]);
}
for(i=0;i<=4;i++)
{
printf("entered [%d] integers are = %s",i, p[i]);
}
return 0;
}
produce a output
Enter the strings to be shorted1
2
3
4
5
6
enetered [0] string is = 1
enetered [1] string is = 2
enetered [2] string is = 3
enetered [3] string is = 4
enetered [4] string is = 5
but when i change limne int* p[5] to char* p[5] for using it as array of pointers to string and do the necessary changes in the above code, it produces segmentation fault.I read ian a book that we cant do this as some garbage value will be assigned to the array of pointers to string.So what can be the possible way to implement the above code with array of pointers to string.
what i want to do is get the strings as input from users and store them in array of pointers to string and then get them printed at initial stage.I am trying to code for simplest string shorting.

Make sure you reserve room for the characters of the strings:
char p[5][128];
and also make sure you limit the length when reading, so scanf() doesn't write outside the buffer:
if(scanf("%127s", p[i]) == 1)
{
p[i][127] = '\0'; /* Make sure it's terminated. */
}

First of all, the int array definition is wrong in your first test. it should be
int p[5];
Second you have to allocate memory for each pointer in your array. each element in your array char *p[5]; is a pointer.
You can use directly by scanf
char *p[5];
for(i=0;i<=4;i++)
{
scanf("%ms\n",&p[i]);
}
But this is not portable is available only for gcc>gcc2.7
or you have to allocate memory each time before scanf()
char *p[5];
for(i=0;i<=4;i++)
{
p[i]=calloc(100,1);
scanf("%99s\n",p[i]);
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
int i;
char *p[5];
printf("Enter the string\n");
for(i=0;i<=4;i++){
char buff[128];
scanf("%127s", buff);
p[i] = strdup(buff);
}
for(i=0;i<=4;i++){
printf("entered [%d] string is = %s\n", i+1, p[i]);
}
for(i=0;i<5;++i) free(p[i]);
return 0;
}

Related

Convert ASCII code to string in C

I am trying to create a char array based on a single ASCII code. The folowing code does not compile correctly, even though "num" is cast to a char:
//Returns the ASCII counterpart of a number, such as 41 = A, 42 = B, 43 = C, etc.
char numToASCII(int num) {
char[] string = {(char)num, "\0"};
return string;
}
For the task that I am given, it is very important that "string" be a character array/string and not a single char. Any help would be appreciated.
The array must be initialized to constant expressions and your function should return a pointer if you want to return an array.
If you just want to return a char, then use the following code instead:
char numToASCII(int num) {
return (char)num;
}
If you want to return a string which contains the character, then you should use the following code:
#include <stdlib.h>
char *numToASCII(int num) {
/*
* Use malloc to allocate an array in the heap, instead of using a
* local array. The memory space of local array will be freed after
* the invocation of numToASCII.
*/
char *string = malloc(2);
if (!string)
return 0;
string[0] = num;
string[1] = 0;
return string;
}
Use the free() function to free the space allocated by malloc().
Try this..
You want to find the character for the ASCII code,then try this code:
#include<stdio.h>
int main()
{
int num;
printf("\nEnter ASCII Code Number:\t");
scanf("%d", &num);
printf("\nASCII Value of %d: \t%c", num, num);
printf("\n");
return 0;
}
In this code it will get the ASCII code from the user and it will print the character for the ASCII code as default.
Not sure if this helps but pulling text from a file comes back as ascii, I needed a string and got around it by checking the string length, sorry for extra steps as I too am very new.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char firstbuff[yourchoice];
char secondbuff[yourchoice];
char sentence[yourchoice];
int stringlenght;
fp = fopen("test.txt", "r");
//Here add a means of counting the lines in the file as linecount
for(int j = 0; j < linecount; j++)
{
fgets(firstbuff; 1000; fp);
//get string length and use for loop to individually ascii copy as characters into array
stringlength = strlen(firstbuff);
for(int i = 0; i < stringlength; i++)
{
secondbuff[i] = (char)firstbuff[i];
}
//string concat
strcat(sentence, secondbuff);
}
printf("%s\n", sentence);
fclose(fp);
}

reading from different files and using strtok on strings

so this is a code that reads 3 strings (orig // test1 // orig_copy) from 2 different files (firstline // secondline)**and calls divide_string to use strtok and take tokens and store them in **(token_orig // token_test // token_orig_copy),
--> this is the problem :
- when i put the three lines in main it does compile and take token from all 3 strings and "Done ." in the end.
-but when i try the next three lines (notice how i changed "HAHAHAH" to "HAHAHAHA", that little changing changes everything and make the program stops at printf("for the string number two :"); .
i hope i cleared the problem
PS : you can past copy the program so you can compile yourself easily
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char s[4] = " ,.";
int divide_string(char* thestring,char** destination)
{
int i=0;
char* token=strtok(thestring,s);
destination[i]=malloc(sizeof(token)+1);
strcpy(destination[i],token);
i++;
printf("the word %d is 'tokened' \n",i);
while(token!=NULL)
{
token =strtok(NULL,s);
if (token != NULL)
{
destination[i]=malloc(sizeof(token)+1);
strcpy(destination[i],token);
printf("the word %d is 'tokened' \n",i);
++i;
}
}
return i;
}
void main ()
{ //TRY THESE THREE LINES THAT WORKS<-----------------------------
char orig[]= "does work HAHAHAH";
char orig_copy[] = "does work HAHAHAH";
char test1[]="does work HAHAHAH";
// char orig[]= "doesnt work HAHAHAHA";
// char orig_copy[] = "doesnt work HAHAHAHA";
// char test1[]="doesnt work HAHAHAHA";
char *token_orig[81];
char *token_test[81];
char *token_orig_copy[81];
strcpy(orig_copy,orig);
printf("for string number one : \n");
int max_orig = divide_string(orig,token_orig);
printf("for string number two : \n");
int a = divide_string(orig_copy,token_orig_copy);
printf("for string number three : \n");
int max_test = divide_string(test1,token_test);
printf("%s-",token_orig[0]);
printf("%s-",token_orig[1]);
printf("%s-\n",token_orig[2]);
printf("%s-",token_orig_copy[0]);
printf("%s-",token_orig_copy[1]);
printf("%s-\n",token_orig_copy[2]);
printf("%s-",token_test[0]);
printf("%s-",token_test[1]);
printf("%s-\n",token_test[2]);
printf("done .");
return 0;
}
Since token is a pointer, sizeof(token) gives you the size of the pointer variable (4 or 8 bytes probably), NOT the number of chars in the string it points to! You want:
strlen(token) + 1
instead (+1 for the \0).
About the only time sizeof is useful for character strings is literals like:
sizeof("Hello World")

How to add string to array of strings in C

So I am getting re-acquainted with C, and this one concept has me particularly stuck.
The goal is to create a dynamically allocated array of strings. I have this done, first creating a null array and allocating the appropriate amount of space for each string entered. The only problem is, when I try to actually add a string, I get a seg fault! I can't figure out why, I have a hunch that it is from improper allocation as I can't see anything wrong with my strcpy function.
I have looked exhaustively on this site for an answer, and I have found help, but can't quite close the deal. Any help you can provide would be greatly appreciated!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int count = 0; //array index counter
char *word; //current word
char **array = NULL;
char *term = "q"; //termination character
char *prnt = "print";
while (strcmp(term, word) != 0)
{
printf("Enter a string. Enter q to end. Enter print to print array\n");
// fgets(word, sizeof(word), stdin); adds a newline character to the word. wont work in this case
scanf("%s", word);
//printf("word: %s\nterm: %s\n",word, term);
if (strcmp(term, word) == 0)
{
printf("Terminate\n");
}
else if (strcmp(prnt, word) == 0)
{
printf("Enumerate\n");
int i;
for (i=0; i<count; i++)
{
printf("Slot %d: %s\n",i, array[i]);
}
}
else
{
printf("String added to array\n");
count++;
array = (char**)realloc(array, (count+1)*sizeof(*array));
array[count-1] = (char*)malloc(sizeof(word));
strcpy(array[count-1], word);
}
}
return ;
}
word has no memory allocated to it. Your program in its current form is trampling over unallocated memory as users enter words into your program.
You should guesstimate how large your input would be and allocate the input buffer like this:
char word[80]; // for 80 char max input per entry

using strcpy for copying string into the element at index retrieved with atoi

Here's the code, which is supposed to execute the first command in history when "history 1" is entered:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[])
{
int i=0; int j=0; int k=0;
char inputString[100];
char *result=NULL;
char delims[] = " ";
char historyArray[100][100] = {0};
char *tokenArray[100][100] ;
do
{
j = 0;
printf("hshell>");
gets(inputString);
strcpy (historyArray[k], inputString);
k++;
// Break the string into parts
result = strtok(inputString, delims);
while (result!=NULL)
{
//result2 = result;
strcpy(tokenArray[j], result);
//puts(result);
j++;
result= strtok(NULL, delims);
//puts(tokenArray[j]);
}
//j = 0;
puts(tokenArray[0]);
puts(tokenArray[1]);
if (strcmp(tokenArray[0], "exit") == 0)
{
return 0;
}
else if (strcmp(tokenArray[0], "history") == 0)
{
if (j>1)
{
strcpy (result,historyArray[atoi(tokenArray[j-1])]);
}
else
{
//print history array
for (i=0; i<k;i++)
printf("%i. %s\n", i+1, historyArray[i]);
}
}
else
{
printf("Command not found\n");
}
}while (1);
}
However, it crashes. When in debugging, I noticed two things: - the array (tokenArray) address is out of bounds and - Access Violation (Segmentation Fault). You can see the errors in the images below.
What am I missing? What am I doing wrong?
The reason why you are dealing with segmentation fault is because you are trying to copy a string into the memory that has not yet been allocated. You have defined result as a char* and just assigned NULL to it, so trying to copy string into it is wrong:
char *result = NULL;
// ...
strcpy(result, historyArray[atoi(tokenArray[j-1])]);
You need to allocate some memory, that result will point to. Then strcpy can be used to copy string into this memory. You can either use malloc to allocate it dynamically or you can define result as an temporary variable with automatic storage duration (i.e. char result[100];).
Also note that
char *tokenArray[100][100];
defines a two-dimensional array of pointers to char. But what you actually need in this case is an array of strings, so you need to get rid of * just like #cnicutar has pointed out.
And one more note:
strcpy(result,historyArray[atoi(tokenArray[j-1])]);
is quite dangerous thing to do, because when atoi fails, you are trying to access the element out of array bounds, which produces undefined behavior, thus I recommend you doing something like this:
char tokenArray[100][100] = {0};
int index;
char indexString[100] = "8";
if (sscanf(indexString, "%d", &index) == 1) // integer successfully retrieved
{
strcpy(tokenArray[index], "some string");
printf("%s", tokenArray[8]);
}
You probably meant char tokenArray[100][100]; which creates 100 tokens with 100 characters each in 1 token.
writing char *tokenArray[100][100] literally means tokenArray is an array of 100 arrays, which contain 100 char *. But each of those char * points to a random addresses if it is not assigned a proper address.
You are getting a segmentation violation error because one of the char * contains an address which you cannot access.

Strings in C Language

How can you code this in C language if the output is like this? I need strings format of the code because our topic is strings.
#include <stdio.h>
#include <stdlib.h>
void main()
{
char my_string[50];
printf("Enter a word:");
scanf("%s", my_string);
printf("Enter a word:");
scanf("%s", my_string);
// Some unknown code here...
// this part is my only problem to solve this.
getch();
}
Output:
Hello -> (user input)
World -> (user input)
HWeolrllod -> (result)
Okay, you need to do some investigating. We don't, as a general rule, do people's homework for them since:
it's cheating.
you'll probably get caught out if you copy verbatim.
it won't help you in the long run at all.
The C library call for user input that you should use is fgets, along the line of:
char buffer[100];
fgets (buffer, sizeof(buffer), stdin);
This will input a string into the character array called buffer.
If you do that with two different buffers, you'll have the strings in memory.
Then you need to create pointers to them and walk through the two strings outputting alternating characters. Pointers are not an easy subject but the following pseudo-code may help:
set p1 to address of first character in string s1
set p1 to address of first character in string s1
while contents of p1 are not end of string marker:
output contents of p1
add 1 to p1 (move to next character)
if contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
while contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
Translating that into C will take some work but the algorithm is solid. You just need to be aware that a character pointer can be defined with char *p1;, getting the contents of it is done with *p1 and advancing it is p = p + 1; or p1++;.
Short of writing the code for you (which I'm not going to do), there's probably not much else you need.
void main()
{
char my_string1[50],my_string2[50]; int ptr;
ptr=0;
printf("Enter a word : ");
scanf("%s",my_string1);
printf("enter a word");
scanf("%s",my_string2);
while(my_string1[ptr]!='\0' && my_string2[ptr]!='\0')
{
printf("%c%c",my_string1[ptr],my_string2[ptr]);
ptr++;
}
if(my_string1[ptr]!='\0')
{
while(my_string1[ptr]!='\0')
{ printf("%c",my_string1[ptr]);
ptr++;
}
}
else
{
while(my_string2[ptr]!='\0')
{printf("%c",my_string2[ptr]);
ptr++;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char my_string1[50],my_string2[50];
int i,l1=1,l2=0;
printf("Enter a word:");
scanf("%s", my_string1);
printf("Enter a word:");
scanf("%s", my_string2);
l1=strlen(my_string1); /* Length of 1st string */
l2=strlen(my_string2); /* Length of 2nd string */
if(l1==l2)
{
for(i=0;i<l1;i++)
{
printf("%c%c",my_string1[i],my_string2[i]);
}
}
else
{
printf("Length of the entered strings do not match");
}
}
This is your required code.
You can see that output needs to be a String containing all chars of User String1 and User String2 one by one...
You can do this like...
//add #include<String.h>
int l1=strlen(s1);
int l2=strlen(s2);
if(l1!=l2)
{
printf("length do not match");
return 0;
}
char ansstr[l1+l2];
int i,j=0,k=0;
for(i=0;i<l1+l2;i=i+2)
{
ansstr[i]=s1[j];
ansstr[i+1]=s2[k];
j++;
k++;``
}
//ansstr is your answer
Ok, here's your code. Come on guys, if he asked here it means he can't solve this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char str1[] = "abcdefghijklmopq";
char str2[] = "jklm";
int len1 = strlen(str1);
int len2 = strlen(str2);
int c1 = 0, c2 = 0;
int max = (len1 > len2) ? len1 : len2 ;
char *result = malloc(len1 + len2);
for(c1 = 0; c1 <= max; c1++) {
if(c1 < len1)
result[c2++] = str1[c1];
if(c1 < len2)
result[c2++] = str2[c1];
}
result[c2] = 0;
printf("\n%s\n", result);
return 0;
}
Basically the loop picks up a character from str1 and appends it to result. Then it picks a character, which stands in the same position as the first from str2 and appends it to result, just as before. I increment c2 by 2 every time because I'm adding 2 chars to result. I check if c1 is bigger that the length of the strings because I want to copy only the characters in the string without the terminating \0. If you know that your strings have the same length you can omit these ifs.

Resources