Issue with String position appending C program - c

I am trying to write program for piglatin. I was not getting the output what I am expecting.
take the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well.
Input : Darrin, what are you doing with 500 and 100?
Output: arrin, hatway reaay ouyay oingday ithway 500 ndaay 100?
Expected Output: arrinday,hatway reay ouyay oingday ithway 500 nday 100?
What's wrong with output : First word not appended with ay
Since I am appending 'ay', I need eliminate the extra 'a' if the word starts with a or end's with 'a'. I just need add ay at the end instead of first letter + ay. For example: Input is Alex and allen are 500 Output should be lexay nday llenay
Also if the starting letter is not alphabet then we should return the same word.
Please help me to solve this
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
static char inputBuffer[100];
static char outputBuffer[100];
void translate (void)
{
char bufferValue;
char firstLetter;
int j = 0, k = 0, m = 0;
printf("\n");
while (j < (sizeof(inputBuffer) - 1))
{
bufferValue = inputBuffer[j];
if (((bufferValue >= 'A') && (bufferValue <= 'Z')) || ((bufferValue >= 'a') && (bufferValue <= 'z')))
{
if (j == 0)
{
firstLetter = bufferValue;
}
else if (inputBuffer[j-1] == ' ')
{
firstLetter = bufferValue;
}
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
}
else if ((bufferValue == ' ') && !(
((inputBuffer[j-1] < 'A') ||
((inputBuffer[j-1] > 'Z') && (inputBuffer[j-1] < 'a')) ||
(inputBuffer[j-1] > 'z'))))
{
printf("%cay%c", firstLetter, bufferValue);
outputBuffer[m] = firstLetter; m++;
outputBuffer[m] = 'a'; m++;
outputBuffer[m] = 'y'; m++;
outputBuffer[m] = bufferValue; m++;
firstLetter = ' ';
}
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
j++;
}
printf("\n final output: %s",outputBuffer);
return;
}
int main(void)
{
printf("enter the string\t");
fflush(stdin);
gets(inputBuffer);
printf ("\nInput buffer contents: %s", inputBuffer);
translate();
return 0;
}

First word not appended with ay
The problem is just not that only the first word is not being appended by first letter and ay, but whenever you have some non alphabet character at the end of a word (digits/special characters, except space), ay will not be appended to that word.
For example, try this input:
Darrin, what, are you doing with 500 and 100?
You'll get the output:
arrin, hat, reaay ouyay oingday ithway 500 ndaay 100?
So mainly, the problem is in the last else you have:
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
See, when , comes immediately after a word, the control comes to this else and it just adds the , as it is, it does not append the firstLetter and ay.
But you can't always append firstLetter and ay in this else, you'll have to come up with some kind of condition, so you could separate the 500 and Darrin,, cause 500 will also go through this else statement.
Maybe, you could try checking if firstLetter is an alphabet or not, if it is, then append the firstLetter and ay, otherwise not.
else
{
if ((firstLetter >= 'a' && firstLetter <= 'z') || (firstLetter >= 'A' && firstLetter <= 'Z'))
printf("%cay", firstLetter);
outputBuffer[m] = firstLetter; m++;
outputBuffer[m] = 'a'; m++;
outputBuffer[m] = 'y'; m++;
firstLetter = ' ';
}
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
But this will still not process the words like 0abcdef,, which do have alphabets in it, but start with some non-alphabet character, so that's your call, if you want to put them to the numbers category (like 500), to leave them as they are, or to process them.
Here is the working example.
P.S. I've made some other changes too (which don't affect your output), but the major change was what I explained (which does).
EDIT:
From the comments below:
If the word starts with Vowel(a,e,i,o,u) then just add y else first letter + ay
You can write a function in your program called isVowel to check if some character is vowel or not:
int isVowel(char c)
{
c = tolower(c);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
return 1;
return 0;
}
Now, you're adding ay at two places in your program:
In the else if and the last else:
outputBuffer[m] = firstLetter; m++;
outputBuffer[m] = 'a'; m++;
outputBuffer[m] = 'y'; m++;
firstLetter = ' ';
So, you can add an if at the statements outputBuffer[m] = 'a'; m++; to only add this a if the firstLetter is not a vowel:
outputBuffer[m] = firstLetter; m++;
if (!isVowel(firstLetter))
{
outputBuffer[m] = 'a';
m++;
}
outputBuffer[m] = 'y'; m++;
firstLetter = ' ';
change this at both places i.e. in the else if and else, and you'll be done.
I've updated the code on ideone

The real problem is that you didn't see the forest through the trees which made the implementation awful to read. To add insult to injury, you decided to break the basic rules of code locality (not using globals unless necessary) and DRY (functions to tell if a charater is a letter exist in the standard library of any language I can think of, don't reimplement it), which made it pretty much irrecoverable as far as maintenance is concerned.
Now, let's read the task description again:
take the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well.
Notice what already stands out because of quoting: word.
So, I'd divide the implementation into two distinct tasks:
Iterate through a sentence word by word.
Once you can reliably identify words, do the piglatin thing.
The end result of might look like this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void piglatinize(const char* in)
{
static const char* SEP = " .,?"; // word separators
// Iterate input by words
const char *sep = NULL, *word = NULL, *end = in;
while (sep = end, // separators from previous word end
word = &end[strspn(end, SEP)], // start of word
end = &word[strcspn(word, SEP)], // end of word
*sep) // iterate until we hit terminating zero character
{
int wordlen = (int)(end - word);
int seplen = (int)(word - sep);
if (wordlen > 0 && isalpha(word[0])) // word starts with a letter, pig it!
{
char firstletter = tolower(word[0]);
const char* suffix = (firstletter == 'a') ? "y" : "ay";
printf("%.*s%.*s%c%s",
seplen, sep, // separators from previous word
wordlen - 1, &word[1], // word without first letter
firstletter, suffix);
}
else // not a real word, just print unchanged
{
printf("%.*s%.*s", seplen, sep, wordlen, word);
}
}
}
int main()
{
piglatinize("Darrin, what are you doing with 500 and 100?");
}
I admit the while loop continuation condition is a handful. If you have trouble understanding this example you might want to read on strspn (and its opposite strcspn) and the comma operator.

Related

Kernighan and Ritchie - exercise 3.3 (expand function)

I have solved the exercises 3.3 from the K&R book. The solution I have implemented seems to work, but is a bit verbose and there could be smarter way to write this code. I wanted to ask if there could be problems with the solution I implemented and if there were easier way to write it:
Write a function expand(s1,s2) that expands shorthand notations like
a-z in the string s1 into the equivalent complete list abc...xyz in
s2. Allow for letters of either case and digits, and be prepared to
handle cases like a-b-c and a-z0-9 and -a-z. Arrange that a leading or
trailing - is taken literally
My code is this one:
#include <stdio.h>
void expand(char s1[],char s2[]){
int j=0,i=0;
while(s1[j] != '\0'){
if (s1[j]>= 'a' && s1[j] <= 'z' && s1[j+1] == '-' && s1[j+1]!='\0' && s1[j+2] >= 'a' && s1[j+2] <= 'z' && s1[j+2] !='\0'){
int z = s1[j+2]-s1[j];
int c;
for (c=0;c<=z;c++){
s2[i]= c+s1[j];
i++;
}
j=j+3;
}
else if (s1[j]>= 'A' && s1[j] <= 'Z' && s1[j+1] == '-' && s1[j+1]!='\0' && s1[j+2] >= 'A' && s1[j+2] <= 'Z' && s1[j+2] !='\0'){
int z = s1[j+2]-s1[j];
int c;
for (c=0;c<=z;c++){
s2[i]= c+s1[j];
i++;
}
j=j+3;
}
else if (s1[j]>= '0' && s1[j] <= '9' && s1[j+1] == '-' && s1[j+1]!='\0' && s1[j+2] >= '0' && s1[j+2] <= '9' && s1[j+2] !='\0'){
int z = s1[j+2]-s1[j];
int c;
for (c=0;c<=z;c++){
s2[i]= c+s1[j];
i++;
}
j=j+3;
}
else if (j!= 0 && s1[j] == '-' && (s1[j-1] < s1[j+1])){
int z = s1[j+1]-(1+s1[j-1]);
int c;
for (c=0;c<=z;c++){
s2[i]= c+(s1[j-1]+1);
i++;
}
j=j+2;
}
else if ( s1[j]>= 32 && s1[j] <= 127 && (s1[j+1] != '-' || s1[j+1]>= 32 && s1[j+1] <= 127 )){
s2[i] = s1[j];
j++;
i++;
}
}
s2[i]='\n';
i++;
s2[i]='\0';
}
int main() {
int c;
char s2[100];
expand("-a-c,a-c-g,A-Z0-9--", s2);
printf("%s",s2);
}
The code works in this way:
First it check if there is a triplet of the kind "x-y" where x<y. Then if gives to the array the values from x to y included and jump to the next character after the triplet "x-y". The same is done for upper case letters and for numbers in further if conditions.
the condition else if (j!= 0 && s1[j] == '-' && (s1[j-1] < s1[j+1])) is used to check for cases like "a-c-d1". The code I have implemented in this example will work like this:
Since we start with the 0-th character in "a-c-d" and the pattern "x-y" is present, "abc" will be assigned to the array. then we will directly jump to the second - in "a-c-f". Since this second - is preceded by a letter "c" and followed by a letter "f", and "c"<"f", then the characters between "c" and "f" will be assigned to the array, excluding the initial "c". Then the index for the string will jump of two and reach 1.
Some other way :
you only to know the last char before - and if it is the same type as current one (lower or upper case letter or digit)
when you get a - and previous char is a letter or digit you know you may have to make expansion
if you have a letter or digit after - and it is corresponding to letter/digit before - you know you can expand from char before / to current one.
you do need to look forward but only save previous char and char before -
you do same kind of processing for each different char type (letter/digit)
You can find an example after :
#include <stdio.h>
// handle different char type
typedef enum E_chartype {
LowerCaseLetter,
UpperCaseLetter,
Digit09,
OtherChar
} E_chartype;
// save if we may have a posdible expansion
typedef enum E_states {
NothingStarted,
StartedExpansion
} E_states;
// find type of a char
E_chartype getCharType(char c) {
if ((c >= 'a') && (c <= 'z'))
return LowerCaseLetter;
if (( c >= 'A') && (c <= 'Z'))
return UpperCaseLetter;
if ((c >= '0') && (c <= '9'))
return Digit09;
return OtherChar;
}
void expandopt(char *inS, char *outS) {
// init output string to null string
outS[0] = 0;
char *endS = outS;
E_states automat = NothingStarted;
char savedChar = 0;
int currentIndex;
E_chartype prevCType=OtherChar,savedCType=OtherChar;
char savedC = 0,prevC=0;
// loop on input string
for (currentIndex = 0; inS[currentIndex] != 0;currentIndex++) {
// save current char in variable c for shorter writting
char c = inS[currentIndex];
printf("%c : ",c);
// save type of current char
E_chartype currentCType = getCharType(c);
switch (automat) {
// genersl case notjing yet started
case NothingStarted:
// possibkee expansion if previous chsr is letter or digit and current char is -
if ((prevCType != OtherChar) && (c == '-')) {
printf("start rep\n");
automat = StartedExpansion;
// save the previous char and its type as it eill br the reference fircexpansion
savedCType = prevCType;
savedC = prevC;
} else {
// reset and cooy current char to iutput
automat = NothingStarted;
printf("nothing\n");
*endS++ = c;
}
break;
case StartedExpansion:
// we make ecpansion only if still same char type and letter/digit is strictly after saved one
if ((currentCType == savedCType) && (c > savedC)){
printf("expansion ");
for (char newC
= savedC+1;newC <= c;newC++) {
*endS++ = newC;
}
// save char in case thrre id a - after, which mean nee expansion
savedC = c;
} else {
// save current chsrcsnd its type
savedCType = currentCType;
savedC = c;
// copy previous char (= -) whch was not vopief in case of expansion
*endS++ = prevC;
*endS++ = c;
}
automat = NothingStarted;
break;
}
// save current chsr and type
prevCType = currentCType;
prevC = c;
}
// add 0 at end of string
*endS = 0;
}
int main() {
expandopt("-a-c,a-c-g,A-Z0-9–",s2);
printf("%s\n",s2);
}
Sorry for the code formatting, I did not find good code editor on phone.

C program to capitalize a word inside quotation marks

I need to build a function that gets an input and capitalizes only the first letter, doesn't print numbers, capitalizes after a . for a new sentence, and capitalizes all words between a double quotation marks ".
This is what I got until now:
#include <stdio.h>
#define MAX 100
int main()
{
char str[MAX] = { 0 };
int i;
//input string
printf("Enter a string: ");
scanf("%[^\n]s", str); //read string with spaces
//capitalize first character of words
for (i = 0; str[i] != '\0'; i++)
{
//check first character is lowercase alphabet
if (i == 0)
{
if ((str[i] >= 'a' && str[i] <= 'z'))
str[i] = str[i] - 32; //subtract 32 to make it capital
continue; //continue to the loop
}
if (str[i] == '.')//check dot
{
//if dot is found, check next character
++i;
//check next character is lowercase alphabet
if (str[i] >= 'a' && str[i] <= 'z')
{
str[i] = str[i] - 32; //subtract 32 to make it capital
continue; //continue to the loop
}
}
else
{
//all other uppercase characters should be in lowercase
if (str[i] >= 'A' && str[i] <= 'Z')
str[i] = str[i] + 32; //subtract 32 to make it small/lowercase
}
}
printf("Capitalize string is: %s\n", str);
return 0;
}
I cant find a way to remove all numbers from input and convert all lowercase to uppercase inside a " plus code for not printing numbers if user input them.
if I input
I am young. You are young. All of us are young.
"I think we need some help. Please" HELP. NO, NO NO,
I DO NOT
NEED HELP
WHATSOEVER.
"Today’s date is
15/2/2021"...
I am 18 years old, are you 20 years old? Maybe 30 years?
output:
I am young. You are young. All of us are young.
"I THINK WE NEED SOME HELP. PLEASE" help. No, no no,
i do not
need help
whatsoever.
"TODAY’S DATE IS
//"...
I am years old, are you years old? maybe years?
The C standard library provides a set of functions, in ctype.h, that will help you
Of particular interest, would be:
isdigit() - returns true if digit
isalpha() - returns true if alphabet character
isalnum() - returns true if alpha/numeric character
islower() - returns true if lower case character
isupper() - returns true if upper case character
tolower() - converts character to lower case
toupper() - converts character to upper case
So, for example, you could replace the test/modify with:
if ( islower( str[i] ) )
{
str[i] = toupper( str[i] );
}
Pedantically, islower() and toupper() return an unsigned int but that's a separate matter...
You can remove letters from a string if you keep two indices, one for reading and one for writing. The following loop will remove all digits from a string:
int j = 0; // writing index, j <= i
int i; // reading index
for (i = 0; str[i]; i++) {
int c = (unsigned char) str[i];
if (!isdigit(c)) str[j++] = c;
}
str[j] = '\0';
(I've used to character classification functions from <ctype.h> mentioned in Andrew' answer.)
This is safe, because j will always be smaller or equal to i. Don't forget to mark the end of the filtered string with the nullterminator, '\0'. You can combine this filtering with your already existing code for replacing characters.
In your code, you capitalize letters only if they are directly behind a full stop. That's usually not the case, there's a space between full stop and the next word. It's better to establish a context:
shift: capitalize the next letter (beginning or after full stop.)
lock: capitalize all letters (inside quotation marks.)
When you read a letter, decide whether to capitalize it or not depending of these two states.
Putting the filtering and the "shift context§ together:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char str[] = "one. two. THREE. 4, 5, 6. \"seven\", eight!";
int shift = 1; // Capitalize next letter
int lock = 0; // Capitalize all letters
int j = 0; // writing index, j <= i
int i; // reading index
for (i = 0; str[i]; i++) {
int c = (unsigned char) str[i];
if (isdigit(c)) continue;
if (isalpha(c)) {
if (shift || lock) {
str[j++] = toupper(c);
shift = 0;
} else {
str[j++] = tolower(c);
}
} else {
if (c == '"') lock = !lock;
if (c == '.') shift = 1;
str[j++] = c;
}
}
str[j] = '\0';
puts(str);
printf("(length: %d)\n", j);
return 0;
}
In order to remove some characters, you should use 2 index variables: one for reading and one for writing back to the same array.
If you are allowed to use <ctype.h>, it is a much more portable and efficient way to test character types.
Also do not use scanf() with protection against buffer overflow. It is as bad as using gets(). Given the difficulty in specifying the maximum number of bytes to store into str, you should use fgets() instead of scanf().
Here is a modified version:
#include <ctype.h>
#include <stdio.h>
#define MAX 100
int main() {
char str[MAX];
int i, j;
unsigned char last, inquote;
//input string
printf("Enter a string: ");
if (!fgets(str, sizeof str, stdin)) { //read string with spaces
// empty file
return 1;
}
last = '.'; // force conversion of first character
inquote = 0;
//capitalize first character of words
for (i = j = 0; str[i] != '\0'; i++) {
unsigned char c = str[i];
//discard digits
if (isdigit(c)) {
continue;
}
//handle double quotes:
if (c == '"') {
inquote ^= 1;
}
//upper case letters after . and inside double quotes
if (last == '.' || inquote) {
str[j++] = toupper(c);
} else {
str[j++] = tolower(c);
}
if (!isspace(c) && c != '"') {
// ignore spaces and quotes for the dot rule
last = c;
}
}
str[j] = '\0'; // set the null terminator in case characters were removed
printf("Capitalized string is: %s", str);
return 0;
}

Solving KNKING exercise 14, chapter 8. Reverse the words

I'm reading K.N.King C programming and I have an issue about it.
I'm solving project 5, chapter 12 which is modify project 14 from chapter 8 by using the pointer .
Project 8.14
Write a program that reverses the words in a sentence:
Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: you can't swallow a cage can you?
Hint: Use a loop to read
the characters one by one and store them in a one-dimensional char
array. Have the loop stop at a period, question mark, or exclamation
point (the "terminating character"), which is saved in a separate char
variable. Then use a second loop to search backward through the array
for the beginning of the last word. Print the last word, then search
backward for the next-to-last word. Repeat until the beginning of the
array is reached. Finally, print the terminating character.
#include <stdio.h>
#include <ctype.h>
#define N 100
int main()
{
char arr[N] = {0};
char *p, *q, mark = 0;
int c;
p = arr;
while((c = getchar()) != '\n' && p < arr + N)
{
if(c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = c;
}
*p = '\0';
while(p >= arr)
{
while(*--p != ' ' && p != arr);
q = p == arr ? arr : p + 1;
while(*q != '\0' && *q != ' ')
{
printf("%c", *q++);
}
if(p >= arr)
printf(" ");
}
printf("\b%c", mark);
printf("\n");
}
the problem is if I enter enter a sentence "My name is jiyong!", expected output is "jiyong is name My!" but the output always has '\xxx'. How can I get rid off? and what is these '\xxx' things?
ran under Xcode 12.4
The second loop looks too complicated to me. You are required to scan the string backwards and print every word found, right? But you're not required to retain the whole sentence...?
So we can replace every space character with zero, thus terminating each word.
while((c = getchar()) != '\n' && p < arr + N)
{
if(c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = (c == ' ') ? '\0' : c;
}
*p = '\0';
Then we can seek words backwards and print them as strings instead of iterating over their characters:
while(--p > arr) // all words except the first one
{
if(!*p && p[1]) //p[1] or *(p + 1)
printf("%s ", p+1);
}
printf("%s", arr); // the first word goes last
if(mark)
printf("%c", mark);
printf("\n");
I assumed p gets incremented at least once in the first loop, that is the input line is never empty. But that seems a valid assumption (although not very safe) as the input is defined as 'a sentence', so it should not be empty...

Hello. My program keeps failing to create the string output I expect. Can you notice a flaw?

This function is meant to fill a second string with the filtered results of the first. the filter should remove all special characters and only print lower case permutations of all letters written
I've tried changing the nature of the "ModifyText" loop, and I've done it with pointers+while loop and with for loops both with the condition of ending when the iterator reaches a character \0.
These are the methods I've already tried, both continue to only return the lowercase "the" of the first word in the string, not the entire string with only lowercase alphabet letters
#include <stdio.h>
#include <ctype.h>
#include <string.h>
//
//int ModifyText(char Stringboy[], char output[])
//{
// for(int i=0; Stringboy[i] != '\0'; i++)
// {
// if(Stringboy[i] >= 'A' && Stringboy[i] <= 'Z')
// {
// output[i] = Stringboy[i] + 32;
//
// }
// else if(Stringboy[i] >= 'a' && Stringboy[i] <= 'z')
// {
// output[i] = Stringboy[i];
// }
//}}
int ModifyText(char *Stringboy, char *output)
{
while(*Stringboy != '\0')
{
if(*Stringboy >= 'A' && *Stringboy <= 'Z')
{
*output = *Stringboy + 32;
}
else if(*Stringboy >= 'a' && *Stringboy <= 'z')
{
*output = *Stringboy;
}
++Stringboy;
++output;
}
}
int main(void){
char samplearray[] = {"THE quick Brown Fox jumps over the Lazy Dog!***!"};
char dummy[83];
printf("Original Text: \n %s\n", samplearray);
ModifyText(samplearray, dummy);
printf("Modified Text: \n %s\n", dummy);
//letterCounter(dummy); //these two bottom functions have their prints written into them, so they need only be called
//wordCounter(dummy);
printf("length of sample array is %d", strlen(samplearray));
}
This code is only returning a string "the" when it should be returning a string "the quick brown fox jumps over the lazy dog" in the string entitled dummy
When *Stringboy is a space then you do not set *output since neither if condition is true. However, you do increment output. As a result the character after "the" in output will be random data (in your case is is probably NULL) which is why the string ends.
Change the code to this:
while(*Stringboy != '\0')
{
if(*Stringboy >= 'A' && *Stringboy <= 'Z')
{
*output = *Stringboy + 32;
}
else
{
*output = *Stringboy;
}
++Stringboy;
++output;
}
*output = '\0';
That way the spaces will be written to the output string.
In your original code, you increment the output pointer also when you didn't copy a letter. You either should write something (e.g. a space) or not increment the output pointer. If you increment the output pointer without writing something, whatever character was there before will stay there. If you're lucky that character is a zero (terminating your string), but it can also be any weird character, including character 7 (a bell sound).
Also, don't forget that your output string needs a terminating zero. Otherwise, weird uninitialized characters might pop up at the end of your string.
int ModifyText(char *Stringboy, char *output)
{
while(*Stringboy != '\0')
{
if(*Stringboy >= 'A' && *Stringboy <= 'Z')
{
*output = *Stringboy + 32;
++output;
}
else if(*Stringboy >= 'a' && *Stringboy <= 'z')
{
*output = *Stringboy;
++output;
}
++Stringboy;
}
*output = '\0'; // make sure the output gets a terminating zero
}
Here is a more fancy version, that outputs spaces to replace non-letters. To not get the output flooded with spaces, a boolean variable checks to maximally output one space between the words.
int ModifyText(char *Stringboy, char *output)
{
bool previousWasLetter = false;
while(*Stringboy != '\0')
{
if(*Stringboy >= 'A' && *Stringboy <= 'Z')
{
*output = *Stringboy + 32;
++output;
previousWasLetter = true;
}
else if(*Stringboy >= 'a' && *Stringboy <= 'z')
{
*output = *Stringboy;
++output;
previousWasLetter = true;
}
else if (previousWasLetter)
{
*output = ' ';
++output;
previousWasLetter = false;
}
++Stringboy;
}
*output = '\0'; // make sure the output gets a terminating zero
}
You have several mistakes:
You copy characters to a new string only if character is an uppercase letter or if the character is lowercase... but you don't copy anything, when it's not either. As you feed the function with an array allocated in the stack (recently allocated, so probably you got a new page zero filled) the character there could be a \0 char and so, delimited the string. You need to copy the character untouched in case it's not an uppercase character... not only if it is lowercase. This will allow you to copy the spaces (which are neither) for example. Resulting in this code:
if(*Stringboy >= 'A' && *Stringboy <= 'Z')
{
*output = *Stringboy + 32;
}
else // if(*Stringboy >= 'a' && *Stringboy <= 'z') // not needed
{
*output = *Stringboy;
}
you dont finalize the output string, putting a \0 character at the end. You should do it past the end of the loop, as the output pointer has been left pointing to the next output char, just add
*output = '\0';
next to the loop.
Some other minor changes (these cannot be considered mistakes, but will silence some warnings got from the compiler on some permitted language inconsistencies you made), like adding a return 0; statement to nonvoid returning functions (this should be a mistake in case you planned to return something from it), change the %d length format for a more portable %zd format string (if you have strlen() returning a long value and int and long are different size, this could lead to problems in some machines), and adding a new line \n character, so the shell prompt gets printed in the next line (and not just after the string length).
So, the code finally should be something like:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
//
//int ModifyText(char Stringboy[], char output[])
//{
// for(int i=0; Stringboy[i] != '\0'; i++)
// {
// if(Stringboy[i] >= 'A' && Stringboy[i] <= 'Z')
// {
// output[i] = Stringboy[i] + 32;
//
// }
// else if(Stringboy[i] >= 'a' && Stringboy[i] <= 'z')
// {
// output[i] = Stringboy[i];
// }
//}}
int ModifyText(char *Stringboy, char *output)
{
while(*Stringboy != '\0')
{
if(*Stringboy >= 'A' && *Stringboy <= 'Z')
{
*output = *Stringboy + 32;
}
else // if(*Stringboy >= 'a' && *Stringboy <= 'z')
{
*output = *Stringboy;
}
++Stringboy;
++output;
}
*output = '\0';
return 0;
}
int main(void){
char samplearray[] = "THE quick Brown Fox jumps over the Lazy Dog!***!"; // braces unneeded.
char dummy[83];
printf("Original Text: \n %s\n", samplearray);
ModifyText(samplearray, dummy);
printf("Modified Text: \n %s\n", dummy);
//letterCounter(dummy); //these two bottom functions have their prints written into them, so they need only be called
//wordCounter(dummy);
printf("length of sample array is %zd\n", strlen(samplearray));
return 0;
}

How can I get the next element of an array in C?

I am new to C, and I have to create a transliterator for my hw assignment at university. In Polish, the sound [tsh] as in chair is represented by two letters: "cz". I have to create a program that will turn every "cz" into 4 (F.e. zaskoczony = zasko4ony). I have a char array(defined at the beginning of the program) and I can get "c" and change it to anything I want, but I'm struggling with getting "z" checked, because I cannot get the +1 element in my string array.
I've tried putting i+1 into the array's brackets, tried using a variable, but nothing seems to work.
while(i<100){
intText[i] = someString[i];
if(intText[i] == 'c'){
int increasedI=i+1;
printf(" %d", increasedI);
if(intText[increasedI] == 'z'){
printf("4");
}
}else{
putchar(intText[i]);
}
i++;
}
How can I get the next element of an array in C?
someString[i + 1]
A problem with OP's code was that it did not advance i an extra 1 nor populated intText[increasedI] before using it.
if(intText[i] == 'c'){
int increasedI=i+1;
printf(" %d", increasedI);
// if(intText[increasedI] == 'z'){
if(someString[increasedI] == 'z'){
printf("4");
}
i++; //add
....
i++;
Also string processing should stop when the null character is reached, not i== 100.
// while(i<100){
while(someString[i]){
Keep separate indexes of reading and writing. Walk down the string, making the desire substation.
As long as the substitution string, example "4", is no longer than the source, "cz", we can do an in-place substitution.
// in-place substitution
size_t in_index = 0;
size_t out_index = 0;
// Loop until end-of-string
while (someString[in_index] != '\0') {
// Test for special combination
if (someString[in_index] == 'c' && someString[in_index + 1] == 'z') {
in_index += 2;
someString[out_index++] = '4';
} else{
someString[out_index++] = someString[in_index++];
}
}
someString[out_index] = '\0';
puts(someString);
Thank everyone for your helpful advice which helped me find my own solution. This is the code which meets my expectations and looks quite simple.
int main()
{
char someString[100] = "cenczetkczacczka";
int i = 0;
while(someString[i] != '\0'){
if(someString[i] == 'c' && someString[i + 1] == 'z'){
printf("4");
i++;
}else{
putchar(someString[i]);
}
i++;
}
return 0;
}

Resources