Lowercase to uppercase letters problems in C - segmentation fault [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
i have a segmentation fault error when i want to run the executable file
void lowerupper(char *s){
int i ;
int a = strlen (s);
printf("%d\n", a);
//fails here segmentation fault
for (i=0 ; i < a-1 ; i++){
if( (s[i] >= 97) && (s[i] <= 122)){
s[i] = s[i] - 32;
}
}
}
int main(void) {
char* string1 = 'HeLlo wOrlD';
printf("%s\n", string1);
lowerupper(string1);
printf("%s\n", string1);
return 0;
}

You can not modify string1. In fact when you declare a string like this
char* string1 = "HeLlo wOrlD";
The string could be stored into a READ-ONLY memory area, it means that you can read it, but not modify it.
If you do
char array[] = "hello world";
Then it creates a read-only string, and copies the characters into array, you'll be able to modify it (into array).
You are invited to declare read-only strings with the keyword const.
const char *string1 = "HeLlo wOrlD";

You might have been passing address of local variable to the function.
You should allocate memory in heap and then pass that variable to function.
This code works here:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
void lowerupper(char *s)
{
int i ;
int a = strlen (s);
printf("%d\n", a);
for (i=0 ; i < a-1 ; i++)
{
if( (s[i] >= 97) && (s[i] <= 122))
{
s[i] = s[i] - 32;
}
}
}
int main(void)
{
char *ss=malloc(10);
strcpy(ss,"hello\n");
lowerupper(ss);
printf("%s",ss);
return 0;
}
Sample Output:
6
HELLO

Related

I keep getting this compiling error: ceasar.c:9:1: error: expected identifier or '(' { [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Hey all I have been trying to do the Cs50 course with harvard and am doing the 2nd week Ceasar assignment. For some reason I can't seem to solve this error and I can't seem to locate what the problem is. I've tried changing the bracket style from { to [ and ( but that isn't working and as far as I can tell I've declared everything correctly. It may have something to do with the semi at the end of the int main() but when I remove it I get another error telling me it should be there. The error message is ceasar.c:9:1: error: expected identifier or '(' { referring to the { between the int num = and the k == argv. I've posted the code below. Any help would be appreciated, thanks!!
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(int argc, string argv[]);
int num;
{
k == argv[2];
if(argc != 2)
{
printf("K not included in command");
return 1;
}
string s = get_string("Insert Lowercase Message:");
for (int i = 0, n = strlen(s); i < n; i++)
{
if (s[i] >= 'A' && s[i] <= 'Z')
{
num = s[i] - 'A';
}
else if (s[i] >= 'a' && s[i] <= 'z')
{
num = s[i] - 'a';
}
Output[i] = (num + k)%26;
}
printf("Secret message %s\n", output[i]);
}
The following lines are problematic:
int main(int argc, string argv[]);
int num;
{
k == argv[2];
if(argc != 2)
You need to remove the semicolon after main;
You need to mov int num to after the opening {;
You need a declaration for k;
You need to check the number of arguments before attempting to assign argv[2] to k;
If you are expecting 2 arguments (argc == 2), then the second argument is at argv[1], not argv[2];
You need to use = for assignment, not ==;
k is an int, whereas argv[1] points to a string representation of an integer value; you will need to use atoi or strtol to convert the contents of argv[1] to the equivalent integer value;
Putting that all together:
#include <stdlib.h> // for atoi
...
int main( int argc, char **argv )
{
int num;
int k;
if ( argc != 2 )
// error
k = atoi( argv[1] );
and proceed from there.
Some words of warning - the CS50 library grossly misrepresents how strings and string processing work in C. Do not expect anything you learn in this course with respect to strings to carry forward in other environments.

Having trouble with recursion [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am trying to make a program which prints all the possible permutations of the string "A?B?AB?" via replacing question marks with A or B. I can't understand why my code works the way it does and need help improving it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* rec(char s[8]){
int i=0;
for(;i<strlen(s);i++){
if(s[i]=='?'){
s[i]='A';
rec(s);
s[i]='B';
rec(s);
s[i]='?';
}
}
for(int k=0;k<strlen(s);k++){
if(s[k]=='?')
i=-1;
}
if(i!=-1)
printf("%s\n",s);
return s;
}
int main(){
char s[8]="A?B?AB?";
rec(s);
}
This should do the trick:
#include <stdio.h>
#include <string.h>
void rec(char *str, int size, int depth){
for (int i = depth; i < size; i++){
if (str[i] == '?'){
str[i] = 'A';
rec(str, size, i + 1);
str[i] = 'B';
rec(str, size, i + 1);
str[i] = '?';
return;
}
}
printf("%s\n", str);
}
int main(){
char s[8] = "A?B?AB?";
rec(s, strlen(s), 0);
}
It's much like August's solution, but I did decide to do some looping until it found the next question mark. That should avoid having too big of a callstack, which could lead to stack overflow, with really big strings. (Note: I didn't test it, so there could still be some minor problems)
You only need to look at one character at a time. Try this:
#include <stdio.h>
void PrintPermutationsFrom(int i, char s[])
{
if (s[i] == '?') {
s[i] = 'A';
PrintPermutationsFrom(i + 1, s);
s[i] = 'B';
PrintPermutationsFrom(i + 1, s);
s[i] = '?';
} else if (s[i] != '\0') {
PrintPermutationsFrom(i + 1, s);
} else {
puts(s);
}
}
void PrintPermutations(char s[])
{
PrintPermutationsFrom(0, s);
}
int main(void)
{
char s[] = "A?B?AB?";
PrintPermutations(s);
return 0;
}
I can't understand why my code works the way it does and need help improving it.
The rec code does simply too much in that after having replaced a ? with both A and B and called itself, it continues iterating over s and generates further output. That is too much because after the first found ?, the recursive invocations already have handled all following ? and generated all arrangements. To correct this, just insert a break; after s[i]='?';.

Continued: Segmentation fault for program that indexes words from a file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am getting a segmentation fault for a program that is supposed to index words read from a file. I changed the first part of my code where I tried to create a dynamic array, realizing that arrays cannot be dynamic. Previously, I used to get a segmentation fault, but now the program compiles but doesn't even run properly. I would highly appreciate some feedback. The link to my previous post is
Segmentation Fault for a Program that Indexes Words from a File
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[])
{
//Check if the usage is correct
if (argc != 2)
{
printf("Usage: ./test15 text\n");
return 1;
}
//Main program
char *file = argv[1];
FILE *ptr = fopen(file, "r");
char ch;
int i = 0;
int k = 0;
int j = 0;
char *text = malloc(sizeof(char));
while ((ch = fgetc(ptr)) != EOF)
{
text[i] = ch;
if (ch == ' ')
{
k++;
}
i++;
}
char *word[k];
i = 0;
int l = 0;
while ((ch = fgetc(ptr)) != EOF)
{
text[i] = ch;
if (ch == ' ')
{
for (int m = j; m < i; m++)
{
int d = i - j;
strncat(word[l], &text[m], d);
}
j = i + 1;
l++;
}
i++;
printf("%s\n", word[l]);
}
return 0;
}
With
char *text = malloc(sizeof(char));
you allocate space for a single char. text is in essence a single-element array.
Then in the following loop, if there's more than a single byte in the file, you will go out of bounds of this single-element array. This leads to undefined behavior.
Furthermore
char *word[k];
here you define an array of uninitialized pointers. Attempting to dereference these pointers also leads to undefined behavior.
And when you use a strcat-like function the destination pointer must be a pointer to a valid null-terminated string.
On another note, the fgetc function return an int. This is actually very important for the comparison against EOF.

Printf prints more character than those contained in my string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have to write a program that acts like a shell. I wrote the function that gets the input from the user. I also wrote the function that splits it into arguments. The first time I type something, it works well, but the second time, it prints different characters after the ones that I gave it. I don't have to print it in the program. I was just doing it to see if it works correctly. I read a bunch of stuff online, but I can't figure out my error. I suppose it is in makeArgs(), but I can't pinpoint it.
Also, when I give it an input, the readline function adds a \n at the end of the string. I suppose it is from the fact that I press the enter key. I managed to solve the issue, by manually replacing it, but I would like to know if it is normal.
Any help really be appreciated.
Thank You
Screenshot of Xterm after 2 inputs.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getText();
int makeArgs();
char *textEntre;
size_t nbCharacters;
char **arguments;
int main (void)
{
while (1){
getText();
int nbArguments = makeArgs();
for(int i =0; i<5; i++){
printf("%s \n",arguments[i]);
}
for(int i=0; i<nbArguments; i++){//free the char ptrs at the end
free(arguments[i]);
}
}
free(textEntre);
free(arguments);
return 0;
}
int getText(){
size_t buffersize = 0;
nbCharacters = getline(&textEntre, &buffersize, stdin);
textEntre[nbCharacters-1] =' '; // when I press enter it regiter the enter as \n so I replace it with a space
return 0;
}
int makeArgs(){
arguments = (char **)malloc(sizeof(char*)*20);
int i;
int j = 0;
int k = 0;
int nbElem = 20; //the number of ptrs that can be in arguments
for(i = 0; i<nbCharacters; i++){
if(i == 20){ //increases the memory allocated if there are more than 20 arguments
nbElem = nbElem *2;
arguments = (char **)realloc(arguments, sizeof(char*)*nbElem);
}
if(textEntre[i] == '"'){ //checks for ""
i++;
while(textEntre[i] != '"'){
i++;
}
}
if(textEntre[i] == ' ' && textEntre[i-1] == ' '){ // eliminates useless spaces
j++;
}
else if(textEntre[i] == ' '){ //save a single argument
char * chptr;
chptr = (char *)malloc(i-j+1); //giving +1 for the \0 at the end
strncpy(chptr, &textEntre[j], i-j);
arguments[k] = chptr;
k++;
j = i +1;
}
}
return k;
}
chptr = (char *)malloc(i-j+1); //giving +1 for the \0 at the end
You properly allocated memory for that terminating \0, but where do you actually add that "\0 at the end"?
strncpy(chptr, &textEntre[j], i-j);
strncpy does not necessarily zero-terminate the destination buffer. You have to do it yourself.
In fact, in this specific application strncpy is a rather inappropriate function: it does not give you anything over ordinary memcpy and might be less efficient. You could just do
memcpy(chptr, &textEntre[j], i - j);
with potentially better efficiency. And, again, don't forget to zero-terminate the destination buffer.
Or you can use sprintf for the same purpose as follows
sprintf(chptr, "%.*s", i - j, &textEntre[j]);
which will produce a properly zero-terminated string in the destination. (Albeit you won't see sprintf used that way very often.)

Accessing a string using counter variable in C/C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In C arrays why is this true? a[5] == 5[a]
In a C++ reference book, I found an example that accessed a string like following:
void main()
{
char *str = "Test";
int len, i;
clrscr();
len = strlen(str);
for(i=0 ; i<len ; i++)
{
printf("%c", i[str]);
}
getch();
}
Why does i[str] work? i is a variable, not an array.
It also works if the string is declared as str[] instead of *str.
Char pointers point to the memory location at the start of a string, and the array indexes (eg, str[i]) are basically adding i iterations to the start of the string.
So, str + i = str[i] = i[str] = i + str
Using this inside printf, like you are doing, all of these will evaluate the same:
printf("%c", str[i]);
printf("%c", i[str]);
printf("%c", *(str+i));
printf("%c", *(i+str));
See also: With arrays, why is it the case that a[5] == 5[a]?
It works because in C i[str] and str[i] are equivalent
i[str] and str[i] evaluate the same way (as *(str+i) )
When you declare str[], str is a pointer to the first element of the array

Resources