Segment fault while reading a string into a char* array - c

I am trying to read some strings and then print them into a matrix form.
int main(int argc, char **argv)
{
char *buffer[BUFFER_SIZE];
for(size_t i = 0; i < BUFFER_SIZE; i++)
{
scanf("%s",buffer[i]); /**This line is causing segment fault **/
}
for(size_t i = 0; i < BUFFER_SIZE; i++)
{
for(size_t j = 0; j < strnlen(buffer[i], MAX); j++ )
{
printf("%c ",buffer[i][j]);
}
printf("\n");
}
}
Any suggestion what I am missing here?

char *buffer[BUFFER_SIZE] is an array of character pointers. The way your code is now, buffer[i] is a char * that is uninitialized at the time you scanf("%s",buffer[i]). You need to allocate memory (malloc, perhaps) for scanf to store the string of characters prior to this point.

Related

In c, when I use %s to print out the contents of a char array it prints blank, but when I loop over it and print each character it works

Just implementing a simple sorting algorithm to sort a string. I tried printing out the buff char array with printf("%s\n") but it came out blank. The contents of the array are there, though, and I checked with printing out each character of it. What am I missing here?
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("usage: ./sortstring string");
exit(1);
}
int size = 1; // 1 to account for '\0'
for (int i = 0; argv[1][i] != '\0'; i++)
{
size += 1;
}
char buff[size];
strcpy(buff, argv[1]);
char temp;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (tolower(buff[i]) > tolower(buff[j]))
{
temp = buff[i];
buff[i] = buff[j];
buff[j] = temp;
}
}
}
// printf("%s\n", buff);
for (int i = 0; i < size; i++)
{
printf("%c", buff[i]);
}
return 0;
}
Change "%c" to "%d" in printf and see the result.
for (int i = 0; i < size; i++)
{
printf("%d", buff[i]);
}
strcpy copies terminating null byte with the source string.
You sorted terminating null byte with other characters.
Your sorting function is probably sorting the null character to position 0.
Instead of attempting to manually count characters in "argc[1]", you could just use the "strlen" function. So, instead of
int size = 1; // 1 to account for '\0'
for (int i = 0; argv[1][i] != '\0'; i++)
{
size += 1;
}
You could use
int size = strlen(argv[1]);
Regards.
The problem is that you're initializing size with 1. I know you did that because you need one more char to \0, but after that, either you need to loop through size - 1 or you can decrease the value of size before your for loops.
Another thing you can do is: initialize size with 0, and use size + 1 while creating your array.

How to convert array contents into a single string C

So the following is a sandbox program. The issue I'm having is combining an array into a single string. I would like to do something similar to the code below:
for (i = 0; i < size_of_array; i++)
{
string += A[i]; // print array
}
The goal is to run a command using popen() and capture the output into a single string. the reason for this is so that I can return the output to a separate function for example:
run_command()
{
return output;
}
main()
{
run_command()
}
Now the exact code that the "sandbox" program is using is down below:
#include <stdio.h>
#include <string.h>
int main()
{
FILE *in;
extern FILE *popen();
char buff[512];
int i, size_of_array;
char A[512][512];
in = popen("ls -lt", "r"); // run command
i = 0;
while(fgets(buff, sizeof(buff), in)!=NULL) // get output into buff
{
strcpy(A[i], buff); // copy buff into array
i ++;
}
pclose(in);
size_of_array = i; // get length or size of array
for (i = 0; i < size_of_array; i++)
{
printf("A[%d]= %s", i, A[i]); // print array
}
return 0;
}
I apologize if this is a noob question, I appreciate the help, thank you!
strcat, strcat_s, or strncat append a string at the end of a destination string (cf. cppreference for strcat). The only thing is to make sure that the destination buffer is large enough. strcat_s can be used to avoid buffer overflows, but is not available on all systems. strncat can be used to avoid buffer overflows, too, yet one needs to track the length of the string within the buffer:
#define maxSize 512*512
char result[maxSize] = { 0x0 };
for (int i = 0; i < size_of_array; i++) {
strcat(result, A[i]);
}
or:
char result[maxSize] = { 0x0 };
for (int i = 0; i < size_of_array; i++) {
strcat_s(result, maxSize, A[i]);
}
or:
char result[maxSize] = { 0x0 };
for (int i = 0; i < size_of_array; i++) {
strncat(result, A[i], maxSize-strlen(result)-1);
}

Using Pointer Strings gives segmentation fault

The task was mainly to use pointers to input a string and slice it at places where there is a '\' character and output them in separate lines, using pointers. The program runs fine when I use arrays instead of pointers. However using pointers to store strings give the message "Segmentation fault". The code is as follows :
#include <stdio.h>
#include <stdlib.h>
int main() {
char *name;
char *sep[100];
int i = 0, j = 0, k = 0;
scanf("%[^\n]s", name);
for(i = 0; (*(name+i)) != '\0'; i++) {
if((*(name+i)) == '\\') {
*((*(sep+k))+j) = '\0';
j = 0;
k++;
} else {
*((*(sep+k))+j) = *(name+i);
j++;
}
}
for(i = 0; i <= k; i++) {
printf("%s\n", *(sep+i));
}
return 0;
}
It would be awesome if you could point out what and where the problem is, instead of giving me an alternative solution. TIA.
your pointers are null pointers.you are invoking undefined behavior by using them without assigning them to allocated memory.Allocate memory to them so that you can use them correctly and store words separated by \.Also,you can use [] instead of *.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char name[256];
char *sep[100];
for( int n = 0 ; n < 100 ; n++ )
{
sep[n] = malloc(30*sizeof(char));
}
int i = 0, j = 0, k = 0;
scanf(" %255[^\n]s", name);
for(i = 0; name[i] != '\0'; i++)
{
if( name[i] == '\\')
{
sep[k][j] = '\0';
j = 0;
k++;
}
else
{
sep[k][j] = name[i];
j++;
}
}
sep[k][j] = '\0';
for(i = 0; i <= k ; i++)
{
printf("%s\n",sep[i]);
}
for( int n = 0 ; n < 100 ; n++ )
{
free(sep[n]);
}
return 0;
}
In your code,
scanf("%[^\n]s", name);
name is an unintialized pointer. It does not point to any valid memory location. You need to allocate memory before you can use it.
The same goes out for sep array, too.
You can consider using an array for this purpose or see the man page of malloc() if you want to stick to a pointer.
FWIW, using an unitialized pointer can lead to undefined behavior.
You must allocate space for your pointers to avoid undefined behaviour: you cannot use a pointer without initializing it.
int main() {
char *name = malloc(MAX_DIM_OF_NAME+1);
char *sep[100];
for (int i=0; i<100; i++)
sep[i] = malloc(MAX_DIM_OF_NAME+1);
....
You call scanf with an uninitialized name.

Getting most frequent characters in array in c

I am trying to get the most frequent characters from an array.
Here's my code
#include <stdio.h>
int main(void)
{
int c[1000];
char input[] = "abcdab";
int i;
for(i=0; input[i]; i++)
{
c[input[i]]++;
}
int j = 0;
char str = 0;
for(i=0; i<256; i++)
{
if(c[i] > j)
{
j = c[i];
str = i;
}
}
printf("%c\n", str);
return 0;
}
It returns 'a'
But I want to get 'a' and 'b' since they are the most frequent characters in the array.
Any help would be appreciated, thank you.
You are passing through the entire array looking for a maximum, and remembering the first one. With the solution you have, you need an additional loop:
for(i=0; i<256; i++){ // Look for all maximums
if(c[i] == j) // If it is the maximum
{
printf("%c\n", i); // print the character
}
}
Note that your array c is not initialized to all zeroes, so it is purely by chance (not really) that the code is working. If you want c to be all zeroes, you need to declare it as int c[1000] = {0}; or to call memset on it.

How can I return an array of strings in an ANSI C program?

How can I return an array of strings in an ANSI C program?
For example:
#include<stdio.h>
#define SIZE 10
char ** ReturnStringArray()
{
//How to do this?
}
main()
{
int i=0;
//How to do here???
char str ** = ReturnStringArray();
for(i=0 ; i<SIZE ; i++)
{
printf("%s", str[i]);
}
}
You could do the following. Error checking omitted for brevity
char** ReturnStringArray() {
char** pArray = (char**)malloc(sizeof(char*)*SIZE);
int i = 0;
for ( i = 0; i < SIZE; i++ ) {
pArray[i] = strdup("a string");
}
return pArray;
}
Note that you'd need to correspondingly free the returned memory.
Additionally in your printf call you'll likely want to include a \n in your string to ensure the buffer is flushed. Otherwise the strings will get queued and won't be immediately printed to the console.
char** str = ReturnStringArray();
for(i=0 ; i<SIZE ; i++)
{
printf("%s\n", str[i]);
}
Do it this way
#include<stdio.h>
#define SIZE 10
char ** ReturnStringArray()
{
//How to do this?
char **strList = (char **)malloc(sizeof(char*) * SIZE);
int i = 0;
if (strList != NULL){
for (i = 0; i < SIZE; i++){
strList[i] = (char *)malloc(SIZE * sizeof(char) + 1);
if (strList[i] != NULL){
sprintf(strList[i], "Foo%d", i);
}
}
}
return strList;
}
main()
{
int i=0;
//How to do here???
char **str = ReturnStringArray();
for(i=0 ; i<SIZE ; i++)
{
printf("%s", str[i]);
}
}
Problem 1: Your double pointer declaration was incorrect
Problem 2: You need to know the size of the string for each pointer in the double-pointer..
Problem 3: The onus is placed on you to free the memory when done with it..
The code sample above assumes that the maximum size of the string will not exceed the value of SIZE, i.e. 10 bytes in length...
Do not go beyond the boundary of the double pointer as it will crash
pls dont typecast the return of malloc, you have not included <stdlib.h> and as someone pointed out above lack of prototype will result in int being casted to char **. Accidently your program may or may not work at all.

Resources