I keep receiving "Segmentation fault (core dumped)".
How can I swap the first letter of a given word that the user inputs to the end of the word and then add an "ay".
For example:
input "Code"
output "odecay"
#include<stdio.h>
#include<string.h>
int main()
{
char pig[100],p[10],i[100];
int j,length;
printf("What word would you like to change into pig latin");
scanf("%s",pig);
length=strlen(pig);
strcat(p,pig[0]);
for(j=0;j<length;j++)
{
pig[j]=pig[j+1];
}
strcat(pig,p);
strcat(pig,"ay");
printf("%s",pig);
return 0;
}
How can I swap the first letter of a given word that the user inputs to the end of the word and then add an "ay"
Save the first character ("letter")
char c = pig[0];
Move the rest of pig one char to the beginning
memmove(pig, pig + 1, strlen(pig) - 1);
alternativly use this statement
memmove(&pig[0], &pig[1], strlen(pig) - 1);
(Note that memcpy() won't work here as source and destiantion overlap.)
Replace the "old" last character with the "old", stored first character
pig[strlen(pig) - 1] = c;
Append "ay"
strcat(pig, "ay");
Print the result:
printf("%s\n", pig);
There is no need for a second "string", char-array.
Assuming pig is large enough, that is one char larger then the data to be scanned in from the user, one can even ommit the use of the intermediate character `c, as per my sketch above.
Initialise pig to all 0s
char pig[100] = "";
Scan in data
scanf("%98s", pig); /* Add tests for failure reading as needed. */
Append the first character of the input, that is copy it to the end of pig
pig[strlen(pig)] = pig[0];
Move all of pig one character to the beginning
memmove(pig, pig + 1, strlen(pig) - 1);
Print the result:
printf("%s\n", pig);
This code runs but there is a slight problem with your algorithm. Since this is probably homework I'll let you figure that part out.
#include <stdio.h>
#include <string.h>
int main()
{
// These should be initialized before use.
char pig[100] = "",
char p[10] = "";
printf("What word would you like to change into Pig Latin: ");
scanf("%s", pig);
unsigned long length = strlen(pig); // strlen returns an unsigned long
strcat(p, &pig[0]); // This needs a pointer to char
for(int j = 0; j < length; j++)
{
pig[j] = pig[j + 1];
}
strcat(pig, p);
strcat(pig, "ay");
printf("%s", pig);
return 0;
}
Input:
Code
Output:
odeCodeay
As I said, the algorithm is not quite right but now that the code runs you should be able to fix it pretty quick. Also, since you are new to programming notice some of the code formatting which makes it more readable.
EDIT
Since others have already mentioned it, changing the line strcat(p, &pig[0]); to strncat(p, pig, 1); will produce the desired output and still use your original algorithm.
strcat(p,pig[0]); // segmentation fault may happen in this line.
char *strcat(char *dest, const char *src) // takes two string but you are passing pig[0] in the second argument which is char
You can use char *strncat(char *dest, const char *src, size_t n)
Thus the proper way to concat a char to a string would be
strncat(p,&pig[0],1); // where 1 is passed in the third argument
//so that it reads only 1 char i.e. pig[0] and ignore next characters
// otherwise the whole pig string will be concatenated.
Related
I want to parse a string into a note and octave. For example if the user inputs "A#4", (A#)-note that will be stored in (char n) and (4)- octave that will be stored in (char o). Why am I getting blanked line instead of 4 as output after A#?
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main()
{
string src = get_string();
char *n;
char *o;
char *note = "ABCDEFG#b";
char *octave = "12345678";
o = strtok(src, note);
n = strtok(src, octave);
printf("%s\n", n);
printf("%s\n", o);
}
Output:
A#
Can you please point to error and suggest a solution?
strtok is not the function you want to use in this instance.
When you call it, it alters the string, replacing the character that matches the deliminator with a NUL so you'll lose the character you're looking for as the note. The second time you call it with src, the string will appear empty and it won't find anything - you're meant to call it on subsequent times with the first parameter set to NULL so that it knows you're searching for the next token in the same string.
You might want to use strspn which counts the number of characters that match your set (ie note) or strpbrk that finds the first character that matches.
Or you could traverse the string yourself and use strchr like this
char *pos;
for(pos=src;*pos!='\0';pos++)
{
if(strchr(note,*pos))
{
// *pos is a note character
}
}
Whatever you use, you'll need to build a new string based on your results as the original string won't have space to put NUL terminators inside to separate out the two parts you're looking for.
my program has two separate functions it excludes non-prime positions and then reserve the output from this. Except the issue I'm having is that at present it is not working how I want it to in the sense that the first function excludes the non prime places and then the second function uses the original input and reserves that instead of the output from function one. I'm new to C so please go easy on me.
#include <stdio.h>
#include <string.h>
void reverse(char[], long, long);
int main()
{
char str[50];
int i, j, k, cnt = 0;
long size;
printf("Enter: ");
scanf("%s", str);
size = strlen(str);
reverse(str, 0, size - 1);
printf(str);
return 0;
}
void reverse(char str[], long index, long size)
{
char temp;
temp = str[index];
str[index] = str[size - index];
str[size - index] = temp;
if (index == size / 2)
{
return;
}
reverse(str, index + 1, size);
}
Sorry for being so vague, a sample output from an input of 1234567 would be 2357 then this output reversed into 7532.
Here is what your code does (as it is written right now):
Input a string from console
Print out every character that is in a "prime position" (2, 3, 5, 7, etc) without modifying the string
Reverse the original, unmodified string
print out the reversed string
It sounds to me that what you are looking for is the following:
When you "exclude characters from a string" you create a new string that you populate with the characters from the input string that are in non-prime positions. Than you use that modified string as a parameter into the reverse() function.
I have no doubt that if you understand the above paragraph you'd have no problem fixing your code.
Here are the steps to achieve what you need:
input string into str (as you currently do)
introduce a new string str2 of the same size 50 as the original string
in your loop copy every character from str into str2 that is not in a "prime position"
call reverse() providing it the str2 as a parameter, not the (current) str
I am currently learning C, and so I wanted to make a program that asks the user to input a string and to output the number of characters that were entered, the code compiles fine, when I enter just 1 character it does fine, but when I enter 2 or more characters, no matter what number of character I enter, it will always say there is just one character and crashes after that. This is my code and I can't figure out what is wrong.
int main(void)
{
int siz;
char i[] = "";
printf("Enter a string.\n");
scanf("%s", i);
siz = sizeof(i)/sizeof(char);
printf("%d", siz);
getch();
return 0;
}
I am currently learning to program, so if there is a way to do it using the same scanf() function I will appreciate that since I haven't learned how to use any other function and probably won't understand how it works.
Please, FORGET that scanf exists. The problem you are running into, whilst caused mostly by your understandable inexperience, will continue to BITE you even when you have experience - until you stop.
Here is why:
scanf will read the input, and put the result in the char buffer you provided. However, it will make no check to make sure there is enough space. If it needs more space than you provided, it will overwrite other memory locations - often with disastrous consequences.
A safer method uses fgets - this is a function that does broadly the same thing as scanf, but it will only read in as many characters as you created space for (or: as you say you created space for).
Other observation: sizeof can only evaluate the size known at compile time : the number of bytes taken by a primitive type (int, double, etc) or size of a fixed array (like int i[100];). It cannot be used to determine the size during the program (if the "size" is a thing that changes).
Your program would look like this:
#include <stdio.h>
#include <string.h>
#define BUFLEN 100 // your buffer length
int main(void) // <<< for correctness, include 'void'
{
int siz;
char i[BUFLEN]; // <<< now you have space for a 99 character string plus the '\0'
printf("Enter a string.\n");
fgets(i, BUFLEN, stdin); // read the input, copy the first BUFLEN characters to i
siz = sizeof(i)/sizeof(char); // it turns out that this will give you the answer BUFLEN
// probably not what you wanted. 'sizeof' gives size of array in
// this case, not size of string
// also not
siz = strlen(i) - 1; // strlen is a function that is declared in string.h
// it produces the string length
// subtract 1 if you don't want to count \n
printf("The string length is %d\n", siz); // don't just print the number, say what it is
// and end with a newline: \n
printf("hit <return> to exit program\n"); // tell user what to do next!
getc(stdin);
return 0;
}
I hope this helps.
update you asked the reasonable follow-up question: "how do I know the string was too long".
See this code snippet for inspiration:
#include <stdio.h>
#include <string.h>
#define N 50
int main(void) {
char a[N];
char *b;
printf("enter a string:\n");
b = fgets(a, N, stdin);
if(b == NULL) {
printf("an error occurred reading input!\n"); // can't think how this would happen...
return 0;
}
if (strlen(a) == N-1 && a[N-2] != '\n') { // used all space, didn't get to end of line
printf("string is too long!\n");
}
else {
printf("The string is %s which is %d characters long\n", a, strlen(a)-1); // all went according to plan
}
}
Remember that when you have space for N characters, the last character (at location N-1) must be a '\0' and since fgets includes the '\n' the largest string you can input is really N-2 characters long.
This line:
char i[] = "";
is equivalent to:
char i[1] = {'\0'};
The array i has only one element, the program crashes because of buffer overflow.
I suggest you using fgets() to replace scanf() like this:
#include <stdio.h>
#define MAX_LEN 1024
int main(void)
{
char line[MAX_LEN];
if (fgets(line, sizeof(line), stdin) != NULL)
printf("%zu\n", strlen(line) - 1);
return 0;
}
The length is decremented by 1 because fgets() would store the new line character at the end.
The problem is here:
char i[] = "";
You are essentially creating a char array with a size of 1 due to setting it equal to "";
Instead, use a buffer with a larger size:
char i[128]; /* You can also malloc space if you desire. */
scanf("%s", i);
See the link below to a similar question if you want to include spaces in your input string. There is also some good input there regarding scanf alternatives.
How do you allow spaces to be entered using scanf?
That's because char i[] = ""; is actually an one element array.
Strings in C are stored as the text which ends with \0 (char of value 0). You should use bigger buffer as others said, for example:
char i[100];
scanf("%s", i);
Then, when calculating length of this string you need to search for the \0 char.
int length = 0;
while (i[length] != '\0')
{
length++;
}
After running this code length contains length of the specified input.
You need to allocate space where it will put the input data. In your program, you can allocate space like:
char i[] = " ";
Which will be ok. But, using malloc is better. Check out the man pages.
I wanted to write a program which counts the occurrences of each letter in a string, then prints one of each letter followed by the count for that letter.
For example:
aabbcccd -
Has 2 a, 2 b, 3 c, and 1 d
So I'd like to convert and print this as:
a2b2c3d1
I wrote code (see below) to perform this count/conversion but for some reason I'm not seeing any output.
#include<stdio.h>
main()
{
char array[]="aabbcccd";
char type,*count,*cp=array;
while(cp!='\0'){
type=*cp;
cp++;
count=cp;
int c;
for(c=1;*cp==type;c++,cp++);
*count='0'+c;
}
count++;
*count='\0';
printf("%s",array);
}
Can anyone help me understand why I'm not seeing any output from printf()?
char array[]="aabbcccd";
char type,*count,*cp=array;
while(cp!='\0'){
*cp is a pointer it's pointing to the address of the start of the array, it will never be == to a char '\0' so it can't leave the loop.
You need to deference the pointer to get what it's pointing at:
while(*cp != '\0') {
...
Also, you have a ; after your for loop, skipping the contents of it:
for(c=1;*cp==type;c++,cp++); <-- this ; makes it not execute the code beneath it
After fixing both of those problems the code produces an output:
mike#linux-4puc:~> ./a.out
a1b1c2cd
Not the one you wanted yet, but that fixes your problems with "printf not functional"
Incidentally, this code has a few other major problems:
You try to write past the end of the string if the last character appears once (you write a '1' where the trailing '\0' was, and a '\0' one character beyond that.
Your code doesn't work if a character appears more than 9 times ('0' + 10 is ':').
Your code doesn't work if a character appears more than 2 times ("dddd" doesn't become "d4"; it becomes "d4dd").
Probably line-buffering. Add a \n to your printf() formatting string. Also your code is very scary, what happens if there are more than 9 of the same character in a row?
1) error correction
while(*cp!='\0'){
and not
while(cp!='\0'){
2) advice
do not use array[] to put in your result user another array to put in your rusel it's more proper and eay
I tried to solve your question quickly and this is my code:
#include <stdio.h>
#define SIZE 255
int main()
{
char input[SIZE] = "aabbcccd";/*input string*/
char output[SIZE]={'\0'};/*where output string is stored*/
char seen[SIZE]={'\0'};/*store all chars already counted*/
char *ip = input;/*input pointer=ip*/
char *op = output;/*output pointer = op*/
char *sp = seen;/*seen pointer=sp*/
char c,count;
int i,j,done;
i=0;
while(i<SIZE && input[i]!='\0')
{
c=input[i];
//don't count if already searched:
done=0;
j=0;
while(j<SIZE)
{
if(c==seen[j])
{
done=1;
break;
}
j++;
}
if(done==0)
{//if i never searched char 'c':
*sp=c;
sp++;
*sp='\0';
//count how many "c" there are into input array:
count = '0';
j=0;
while(j<SIZE)
{
if(ip[j]==c)
{
count++;
}
j++;
}
*op=c;
op++;
*op=count;
op++;
}
i++;
}
*op='\0';
printf("input: %s\n",input);
printf("output: %s\n",output);
return 0;
}
It's not a good code for several reasons(I don't check arrays size writing new elements, I could stop searches at first empty item, and so on...) but you could think about it as a "start point" and improve it. You could take a look at standard library to copy substring elements and so on(i.e. strncpy).
I've been trying to solve this for hours. Including research, but no go. Basically, we have to create function with :
int reverseSentence(char** sentence, char ** newsentance, int maxWords){
Where it returns the number of words in a sentence.
Here's more information:
You must maintain sentence capitalization, meaning if the sentence was capitalized, keep the
capital. If a word was capitalized, such as a name, retain the capital
The parameter sentence is a reference to a character array with the sentence to
reverse and should not be directly modified by your function. Each word is an array
entry in sentence.
The parameter newsentance is a reference to a character array to hold the new
sentence.
The parameter maxWords is the maximum size of the character array.
Return the number of words in the sentence
Do not copy the strings to temporary storage and replace them in the sentence. Move
the pointers.
ex: “To be, or not to be: that is the question.” becomes ”Question the is that be: to not or be, to.
Now, the problem I have is, currently my code works. But I can't seem to think of a way to capitalize something without getting an error. (Since we can't make a new storage).
What I have here is basically part of my code:
char ** fptr = sentence; //front sentence
char ** lptr = sentence; //last sentence
char ** nptr = newsentance;//front of new sentance
if( isupper(**fptr)){ //if the first letter of the first word is capital set flag
capflag = 1;
}
// find last word before null sentence and also calculate size
while(**(++lptr))
++size;
--lptr;
if(capflag){
*nptr = *lptr;
**nptr = toupper(**lptr); //error here
}
Also, I had to assume that the last "word" in sentence is "" or I can't find a way to calculate the size of the sentence. I hope someone can help me out.
I used this to test:
char ** test = malloc(1000);
*test = "To ";
*(test+1) = "be ";
*(test+2) = "or ";
*(test+3) = "not ";
*(test+4) = "to ";
*(test+5) = "be ";
*(test+6) = "";
char ** ztest = malloc(1000);
int rs = reverseSentence(test, ztest, 1000 );
Your code tries to modify a string literal, which is undefined behavior (you cannot do "ABC"[1] = 48; some implementations put string literals to readonly memory).
Try allocating space using malloc for each individual string and copy data from each string literal using memcpy.
The code below gives me the output:
To be or not to be; that is the question.
Number of words: 10
To be or not to be; that is the question.
question. the is that be; to not or be To
It only shuffles (copies of) pointers around; it does not attempt to modify the capitalization of words. If was going to do that, it would have to work harder, allocating copies of the leading word in the original sentence (but how would you tell whether that was a name or not?) and the last word. Suppose the sentence was "London hosted the 2012 Olympics"; when reversed, you don't want to case-convert the L of London because it is a name that happens to start the sentence (and you don't need to case-convert the O of Olympics either).
You could legitimately decide that the full stop (period) at the end of the sentence should not be included in the data (so my "question." should be replaced by "question"), and then have the sentence printing code add the full stop at the end; it is a trivial modification.
#include <stdio.h>
int reverse_sentence(char **fwd_order, char **rev_order, int max_words)
{
char **end = fwd_order;
int num_words = 0;
for (end = fwd_order; *end != 0 && num_words < max_words; end++)
num_words++;
for (int i = 0; i < num_words; i++)
*rev_order++ = *--end;
*rev_order = 0;
return num_words;
}
static void print_sentence(char **words)
{
const char *pad = "";
while (*words)
{
printf("%s%s", pad, *words++);
pad = " ";
}
putchar('\n');
}
int main(void)
{
char *sentence[] =
{ "To", "be", "or", "not", "to", "be;", "that", "is", "the", "question.", 0 };
enum { NUM_WORDS = sizeof(sentence) / sizeof(sentence[0]) };
char *reversed[NUM_WORDS];
int num_words;
print_sentence(sentence);
num_words = reverse_sentence(sentence, reversed, NUM_WORDS);
printf("Number of words: %d\n", num_words);
print_sentence(sentence);
print_sentence(reversed);
return(0);
}
ex: “To be, or not to be: that is the question.” becomes ”Question the is that be: to not or be, to.
Is this part of the specification or is it your interpretation? If the latter, you should verify whether your interpretation is correct or whether you are to simply reverse the order of the words, which is easily achievable. Do you even know if you are required to handle punctuation? Your code doesn't, and your test doesn't match your example.
First rule of software engineering: nail down the requirements.