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.
Related
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.
int main(){
char* str = "bake", *temp = str;
char alpha [] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for (int i = 0 ; temp[i] != '\0'; i++) {
for (int j = 0; alpha[j] != '\0'; j++) {
temp[i] = alpha[j];
printf("%s\n",temp);
}
temp = str;
}
return 0;
}
Why am I trying to replace a character in a particular location it falls to me?
i want it print me like that
i = 0 (index 0 he change only the first char).
aake
bake
cake
dake
....
i = 1(index 1 he change only the second char).
bake
bbke
bcke
bdke
....
i don't understand why temp[i] = alpha[j]
not work... what i need to do that i can change the char.
thank you a lot for helps
![enter image description here][1]
[1]: https://i.stack.imgur.com/v0onF.jpg
As said in the comments, there are a couple of mistakes in your code. First of all, as stated by bruno you cannot modify a literal string. Secondly, when you write *temp=str you are saying "the pointer temp now points to the same adress as str", in short, doing this, if you modify the array in temp you will modify the array in str as well, and vice-versa, because they are the same.
Below you have a possible solution using malloc to create a new array in temp and strcpy to copy str to temp after each outter cycle
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char str[]= "bake",*temp;
temp=malloc((strlen(str)+1)*sizeof(char));
strcpy(temp,str);
char alpha [] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
for (int i = 0 ; temp[i] != '\0'; i++) {
for (int j = 0; alpha[j] != '\0'; j++) {
temp[i] = alpha[j];
printf("%s\n",temp);
}
strcpy(temp,str);
}
return 0;
}
I have a core dumped and I don't know why. Here is the code:
#include <stdio.h>
int str_size(char *str) {
int size = 0;
for (int i = 0 ; str[i] != '\0' ; i++) {
size++;
}
return (size);
}
int find_char(char c, char *str) {
int place = 0;
for (int i = 0 ; str[i] != '\0' ; i++) {
if (c == str[i]) {
place = i;
}
}
return (place);
}
char *convert_dec_to_base(int n, char *base) {
char n_based[64];
char converted_b[64];
for (int i = 0 ; n != 0 ; i++) {
n_based[i] = base[n % str_size(base)];
n /= str_size(base);
}
for (int i = 0 ; i < str_size(n_based) ; i++) {
converted_b[str_size(n_based) - i - 1] = n_based[i];
}
return (converted_b);
}
int main(void) {
printf("%s\n", convert_dec_to_base(32, "0123456789ABCDEF"));
printf("%c\n", t[1]);
return (0);
}
This code will convert a decimal integer into a given base. It will return a char* containing the base transformed integer.
converted_b is a variable local to the function, returning it results in undefined behavior, you can declare it as a pointer and allocate memory in order to be able to return it:
#include <stdlib.h>
char* converted_b = malloc(64);
In this case the program will end there, but in a normal situation, when you are finished using it, you should then free the memory previously allocated:
char* str = convert_dec_to_base(32, "0123456789ABCDEF");
printf("%s\n",str);
free(str);
As an alternative, as #CraigEstey mentioned in the comment section you can use static storage:
static char converted_b[64];
This will ensure the lifetime of the variable is the same as the program itself.
I'm currently learning the C programming language, and I'm having some issues with it.
I'm getting Segmentation Error quite a lot when dealing with string (A.K.A char tables)
Here a simple algorithm just to delete the 'e' letter in the input string.
Example:
"hackers does exist" ->>> "hacks dos xist"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
char T[200];
int j,i,l,times=0;
printf("Entre THE TXT\n");
gets(T);
while (T[i] != '\0')
{
l++;
i++;
}
for (i=0;i<l;i++)
{
if ( T[i] == 'e')
{
times++;
}
}
l=l-times;
i=0;
j=0;
while (i<l)
{
if ( T[j] != 'e')
{
T[i]=T[j];
i++;
j++;
}
else j++;
}
for (i=0;i<l;i++)
{
printf("%c",T[i]);
}
return 0;
}
Can you please tell me what I did wrong?
PS: I have noticed that each time I do incrementation as j++ in this code I will get the Segmentation Error... I really don't understand why.
Initialize i, j, l variables. Since uninitialized local variables are indeterminate. Reading them prior to assigning a value results in undefined behavior.
You are accessing the i and l variable without initialization.
while (T[i] != '\0')
{
l++;
i++;
}
Initialize as below.
int j = 0, i = 0, l = 0, times = 0;
As kiran Biradar already answered you only missed to initialize your integers.
You have several options here. I'll write them from most common to most discouraged.
Most used form, verbose but easier to maintain later.
int i = 0;
int j = 0;
int l = 0;
int times = 0;
Short form 1:
int i = 0, j = 0, l = 0, times 0;
Short form 2:
int i, j, l, times;
i = j = l = times = 0;
I'd suggest you also to use the features of at least the C99 Standard and reduce the scope of your variables completely. (Yes I know it's possible with {}-Blocks but I kinda like for-loops, if you iterate completely over something.
Hence my suggestion for your code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // str(n)len
int main(void) // argv/argc is never used
{
char text[200];
printf("Entre THE TXT\n");
if (fgets(text, sizeof(text), stdin) == NULL) // fgets as gets is deprecated
exit(EXIT_FAILURE);
size_t len = strlen(text); // returns number of Characters excluding '\0'
if (len > 0 && text[len-1] == '\n') { // strip newline if present from fgets
text[len-1] = '\0';
}
unsigned int times = 0;
for (size_t i=0; i<len; i++) {
if (text[i] == 'e') {
times++;
}
}
// I'd prefer to use a `newlen` variable
len -= (size_t) times;
for (size_t j=0, i=0; i < len; j++) {
if (text[j] != 'e') {
text[i] = text[j];
i++;
}
}
text[len] = '\0'; // just for safety reasons terminate string properly
puts(text); // Use puts instead of calling printf several times.
return 0;
}
Further improvements:
Actually the times could be eliminated, as it's not really used to delete es.
So just remove the times block and all lines with it.
I'm trying to take a string and break it into "word" components and store that in an array of strings.
"Hello my name is Bill." should give back a char** with elements, "Hello", "my", "name", "is", and "Bill."
My code will compile however I keep encountering a runtime error (I don't get warnings anymore and my debugger gdb doesn't work)>
I'm running on minGW on Window 8.
#include <stdio.h>
#include <stdlib.h>
char** words(char* string)
{
int i = 0;
int j = 0;
int k =0;
int count = 0;
char** stringArray = (char**) malloc(sizeof(char)*30*30);
while( string[i] != '\0' )
{
if(string[i] != ' ')
{
j =0;
while(string[i+j+1] != ' ')
{
j++;
}
i = i+j;
for(k=0; k<=j; k++)
{
stringArray[count][k] = string[i+k];
}
count++;
}
i++;
}
return stringArray;
}
int main()
{
char message[20] = "abcd efgh ijkl mno";
char** wordArray = words(message);
printf("%c\n\n", wordArray[0][0]);
int i =0;
while(wordArray[i])
{
printf("%s\n", wordArray[i]);
i++;
}
printf("\nThe problem is not with the words function");
return 0;
}
There are couple of issues that have been mentioned in the comments.
The allocation should look something like:
#include <ctype.h> // for isspace()
#define MAXSTRLEN 30 // using a symbolic constant
char **stringArray;
int i, j, k;
stringArray = malloc(sizeof(char*) * MAXSTRLEN); // don't cast from malloc
for (i = 0; i < 30; ++i) {
stringArray[i] = malloc(sizeof(char) * MAXSTRLEN);
}
// TODO error checking: malloc could return NULL
while copying the substrings would look like:
i = 0;
j = 0;
while( string[i] != '\0') // go through the whole string
{
while (string[i] != '\0' && isspace(string[i])) {
i++; // skip whitespaces
}
k = 0;
while (string[i] != '\0' && !isspace(string[i])) { // copy word until whitepace or end of string
stringArray[j][k++] = string[i++];
}
stringArray[j][k] = '\0'; // EOS !!!
j++;
}
and printing (j is number of words actually read):
for (i = 0; i < j/*30*/; ++i) { // (!) how to print
printf("%s\n", stringArray[i]);
}
And, yes strtok would also do the job.
In words() you're assigning values to stringArray as a two-dimensional array, and in main() you're reading values from it as an array of pointers. Those are not the same thing.
So you need to change it so that you're consistently treating it as a 2D array, or so that you're consistently treating it as an array of pointers (char* to be exact). Either will work... see the comments above for elaboration.
This code is all wrong.
char** stringArray = (char**) malloc(sizeof(char)*30*30);
First of all, sizeof(char) is always one, second, you don't need to cast a void. So:
char **stringArray = malloc(30 * 30);
But that doesn't make any sense because it's an array of char *, so you should allocate in terms of that:
char **stringArray = malloc(sizeof(char *) * 30);
Or even better:
char **stringArray = malloc(sizeof(*stringArray) * 30);
So now you have an array with 30 char *, but each of those is not initialized, so you need to do that:
for (i = 0; i < 30; i++)
stringArray[i] = malloc(sizeof(**stringArray) * 30);
If you don't do that, you can't access stringArray[count][k].
And then you assume the last element in the array is NULL, but you never set it, so you either do stringArray[count] = NULL at the end of words(), or you do calloc() instead of malloc().
I'm not analyzing the code beyond that; it's just all wrong.