Replace provided string with user input string? - arrays

I will preface this with the fact that this was once working. I added a print statement (now gone) that simply asked the user to input strings.
The input is done through the following method:
./Project aa b
aa was the code to be replaced, and b was going to be the letter replacing it for any occurrences in the user's input.
so for
./project Timmy Johhny
Timmy strolled through the park
the output would be
Johhny strolled through the park.
And as I said, it did work, and after it just printed spaces.
My code looks as follows:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * isMatch(char* os, char* ns, char* us){
int i;
int oslen, nslen, uslen;
int it = 0;
uslen = strlen(us);
oslen = strlen(os);
nslen = strlen(ns);
for(i=0; i < uslen; i++){
if(strstr(&us[i], os) == &us[i]){
it = it + 1;
i = i + oslen - 1;
}
}
char *ans = malloc(uslen + nslen * it);
int anslen = uslen + nslen * it;
i = 0;
while(*us){
if(strstr(us, os) == us){
strcpy(&ans[i], ns);
i = i + nslen;
us = us + oslen;
}
else
ans[i++] = *us++;
}
return ans;
}
int main(int arg1, char * argp[]){
char input[100];
int i;
char c;
while(1){
if(scanf("%c",&c)==EOF){
break;
}
if( (input[0]=c) != '\n'){
for(i=1;i<100;i++){
scanf("%c", &input[i]);
if(input[i] == '\n'){
break;
}
// char *match = isMatch(argp[1],argp[2],&input[i]);
// printf("%s", match);
// free(match);
}
char *match = isMatch(argp[1],argp[2],&input[i]);
printf("%s", match);
free(match);
}
}
}
Is there just a small error I made, or is it something larger.
I tried to move the printf in and out of a for loop amongst everything else, and simply got increasingly strange outputs.
Thank you!

Related

I am writing a code about replacing a word in a string with another word and removing repeats. Cannot finish it but got half to work [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 2 years ago.
Improve this question
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
//This function converts a string to a sentence.
void
StrtoSent(char *string)
{
int length = 0,n = 0;
length = strlen(string);
for(n = 0; n < length; n++){
if((n ==0) && (string[n] >= 'b' && string[n] <= 'y')){
string[n] = string[n] - 32;
}
else if(string[n] == '.'){
if(string[n + 1] == ' '){
if(string[n+2]>= 'b' && string[n+2]<= 'y'){
string[n+2]= string[n+1] - 32;
}
}
}
}
}
int
main(void)
{
char string[50] = {0};
int length = 0,n = 0,a = 0,d = 0;
printf("\n\nEnter a wordstring Neo: ");
gets(string);
StrtoSent(string);//Here,we send the string off to the function
char str[] = "The xitraM is acutally the Matrix!";
char j[] = "xitraM";
char e[] = "Matrix";
char *result = NULL;
printf("Original string: %s\n",str);
printf("The converted sentence: %s",string);
char input[200];
getchar();
fflush(stdin);
fgets(input,200,stdin);
char c;
if (isdigit(c)) {
int n = c - '0'; //'0'-'9' -> 0 - 9
printf("%c is coverted to %d\n",c,n);
}
while((c=getchar()) != EOF) {
if(islower(c))
printf("%c will be converted to %c\n",c,toupper(c));
if(isupper(c))
printf("%c in lowercase is %c\n",c,tolower(c));
getchar();
}
}
How do I replace the word xitraM and get it to be like this output:
The xirtaM is actually the MATRIX!
Converted sentence:
The Matrix is actually the MATRIX!
Original:
a blACk cAT is in the xirtaM.
Converted sentence:
A Black Cat is in the Matrix.
My code allows you
so far to enter a wordstring and it will return a string, and it will
fix the //code if there are capitals in the wrong place and if the
punctuation is wrong, but I cannot seem to get the code to replace
xitraM with Matrix and I am stuck on that.
Some help would be great -- thanks!
This is prefaced by my top comments.
There are many issues with the code.
Never use gets--the man page for it says to not use it [and why].
Your main is reading a line but not doing much with it.
The loop at the bottom doing getchar makes no sense because you've already read the line with the fgets above. It looks like you're trying to preview the capitalization.
For the word substitution, use two buffers. An input and a separate output buffer. Although xirtaM and Matrix are the same length, using separate buffers allows the length of the strings to differ (i.e. it's more general).
You can loop through the input using strstr to find the "bad" string. Then, copy over the partial string that precedes it. Skip the bad string in the input. Then, copy over the "good" string to the output.
Your capitalization function makes no sense [and appears to do nothing].
Also, converting the "black cat" string, from your example isn't general because it would need to special case "cat" to produce "Cat". For English, "cat" is not a proper name, so it should be all lowercase.
Unfortunately, your code needed some heavy refactoring in order to work.
I had to change the capitalization function to just capitalize the first char of the first word of each sentence as that was the only thing that made sense to me [adjust to suit your needs].
I wired in your two test cases. And, I've added some debug printf statements.
Anyway, here's the code. I've annotated it, so that the part you had an issue with [the word substitution] should give you some ideas.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
//This function converts a string to a sentence.
void
StrtoSent(char *string)
{
int length = 0,n = 0;
length = strlen(string);
for(n = 0; n < length; n++){
if((n ==0) && (string[n] >= 'b' && string[n] <= 'y')){
string[n] = string[n] - 32;
}
else if(string[n] == '.'){
if(string[n + 1] == ' '){
if(string[n+2]>= 'b' && string[n+2]<= 'y'){
string[n+2]= string[n+1] - 32;
}
}
}
}
}
// fixcap -- capitalize sentences in the string
void
fixcap(char *string)
{
int capflg = 1;
while (1) {
int chr = *string;
// end of string
if (chr == 0)
break;
switch (chr) {
case ' ':
break;
case '.': // end of sentence -- restart capitalization
case '!':
capflg = 1;
break;
default:
// capitalize the [first letter of the] first word of a sentence
if (capflg) {
chr = toupper((unsigned char) chr);
capflg = 0;
}
else
chr = tolower((unsigned char) chr);
break;
}
*string++ = chr;
}
}
// fixword -- substitute word in string
void
fixword(char *out,const char *inp,const char *bad,const char *good)
{
int lenbad = strlen(bad);
int lengood = strlen(good);
char *cp;
int lencpy;
while (1) {
// find the "bad" string in the input
cp = strcasestr(inp,bad);
// the remaining input string is good -- copy it
if (cp == NULL) {
strcpy(out,inp);
break;
}
// get the length of the string leading up to the "bad" string
// copy it over and advance the pointers
lencpy = cp - inp;
memcpy(out,inp,lencpy);
inp += lencpy;
out += lencpy;
// skip over the bad string in the input
inp += lenbad;
// copy over the "good" string and advance the output pointer
strcpy(out,good);
out += lengood;
}
}
// fixall -- perform all actions
void
fixall(const char *string)
{
char inp[1000];
char out[1000];
strcpy(inp,string);
printf("DEBUG: BEFORE '%s'\n",inp);
//Here,we send the string off to the function
#if 0
StrtoSent(inp);
printf("DEBUG: AFTCAP '%s'\n",inp);
#endif
#if 1
fixcap(inp);
printf("DEBUG: AFTCAP '%s'\n",inp);
#endif
fixword(out,inp,"xirtaM","Matrix");
printf("DEBUG: AFTFIX '%s'\n",out);
}
// doline -- read and process an input line
int
doline(void)
{
char *cp;
char string[1000];
int more;
do {
printf("\n\nEnter a wordstring Neo: ");
cp = fgets(string,sizeof(string),stdin);
more = (cp != NULL);
if (! more)
break;
// strip newline
cp = strchr(string,'\n');
if (cp != NULL)
*cp = 0;
fixall(string);
} while (0);
return more;
}
int
main(void)
{
#if 0
char string[50] = {0};
int length = 0,n = 0,a = 0,d = 0;
#endif
// default test cases
fixall("The xirtaM is acutally the Matrix!");
fixall("a blACk cAT is in the xirtaM.");
// read input lines and do conversions
while (1) {
if (! doline())
break;
}
#if 0
char str[] = "The xirtaM is acutally the Matrix!";
char j[] = "xirtaM";
char e[] = "Matrix";
char *result = NULL;
printf("Original string: %s\n",str);
printf("The converted sentence: %s",string);
char input[200];
getchar();
fflush(stdin);
fgets(input,200,stdin);
char c;
if (isdigit(c)) {
int n = c - '0'; //'0'-'9' -> 0 - 9
printf("%c is coverted to %d\n",c,n);
}
while((c=getchar()) != EOF) {
if(islower(c))
printf("%c will be converted to %c\n",c,toupper(c));
if(isupper(c))
printf("%c in lowercase is %c\n",c,tolower(c));
getchar();
}
#endif
return 0;
}
Here is the program output for the default test cases:
DEBUG: BEFORE 'The xirtaM is acutally the Matrix!'
DEBUG: AFTCAP 'The xirtam is acutally the matrix!'
DEBUG: AFTFIX 'The Matrix is acutally the matrix!'
DEBUG: BEFORE 'a blACk cAT is in the xirtaM.'
DEBUG: AFTCAP 'A black cat is in the xirtam.'
DEBUG: AFTFIX 'A black cat is in the Matrix.'

Issue with Strings in C

Here is a program with Strings where I am trying
Pig Latin translation is simply taking the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well
I have issue with m1=m2+3 ( resetting the Initial Marker ).
Input that I am giving : "Alex, how are you right"
The output I am expecting is : lexay, owhay reay ouyay ightray
But
I am getting this : lex,Aay way ay ayo gayi
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void initialize(char english[], char piglatin[]);
void readinput (char english[]);
int countwords(char english[]);
void convert ( int words, char english[], char piglatin[]);
void writeoutput( char piglatin[]);
int main()
{
char english[80], piglatin[80];
int words;
initialize(english, piglatin);
printf("enter the string\t");
fflush(stdin);
gets(english);
printf ("\nInput buffer contents: %s\n", english);
words = countwords(english);
convert(words,english,piglatin);
writeoutput(piglatin);
printf ("Have a nice day\n");
}
void initialize(char english[], char piglatin[])
{
int count;
for(count =0; count<80;++count)
{
english[count]=piglatin[count]=' ';
}
return;
}
/* Scan the english test and determine the number of words */
int countwords(char english[])
{
int count, words =1;
for ( count =0;count <79;++count)
{
if(english[count]==' ' && english[count+1]!=' ')
++words;
}
printf("%d\n",words);
return (words);
}
/* convert each words in to piglatin*/
void convert ( int words, char english[], char piglatin[])
{
int n, count;
int m1=0;
int m2;
/* convert each word */
for ( n=1;n<=words;++n)
{
/* locate the end of the current word*/
count = m1;
printf ("\ before conversion word contents: %d\n", count);
while ( english[count]!=' ')
{
m2=count++;
}
printf ("\ before conversion word contents: %d\n", m2);
/* transpose the first letter and add 'a', 'y'*/
for (count =m1;count<m2;++count)
{
piglatin[count+(n-1)]=english[count+1];
}
piglatin[m2+(n-1)] = english[m1];
piglatin[m2+1] = 'a';
piglatin[m2+2] = 'y';
m1=m2+3;
printf ("\ Converted word contents: %s\n", piglatin);
}
return;
}
void writeoutput( char piglatin[])
{
int count =0;
for (count =0; count <80; ++count)
{
putchar(piglatin[count]);
}
printf ("\n");
return;
}
I see various problems here:
Alex -> lex,Aay: You should check for punctuation marks when determining the end of the words, thus inserting the Aay part before the comma character
Alex -> lex,Aay: Every character from the start of a word should be converted to lowercase and the resulting first character should be converted to upper case respectively
Now the conversion function: I have changed it a bit to get you started; it should work now ( at least it does with your test string ) without taking 1 and 2 into account though
void convert(int words, char english[], char piglatin[])
{
int estart = 0;
int ppos = 0;
int m2;
for (int n = 0; n < words; n++)
{
//locate the start of the current word, to make
//sure something like this is converted:
//"Alex, how are you"
while (english[estart] == ' ')
{
//make sure we do not exceed the strings boundaries!
if (english[estart] == '\0')
{
return;
}
estart++;
}
//locate the end of the word
int eend = estart;
while (english[eend] != ' ')
{
//never forget to check for the end of the string
if (english[eend] == '\0')
{
break;
}
eend++;
}
/* transpose the first letter and add 'a', 'y'*/
for (int i = estart+1; i < eend; i++, ppos++)
{
piglatin[ppos] = english[i];
}
piglatin[ppos++] = english[estart];
piglatin[ppos++] = 'a';
piglatin[ppos++] = 'y';
//dont forget to add a whitespace or your string might behave
//very stangely!
piglatin[ppos++] = ' ';
estart = eend;
printf("\ Converted word contents: %s\n", piglatin);
}
}
I hope this gets you started in the right direction.
Please also check your array sizes for english and piglatin. The string for piglatin is alway longer than the english one but your array sizes are the same! Also i would advise you add some boundary checks to make sure you do not leave the array boundaries.

strings to arrays then print in c

I am trying to take a user inputted string and look at each code to see if it appears in another string of strings. So far my code works.
If the word is successfully found then the alpha representation is to be added to an array that will eventually be printed, but only if all codes were found.
I am having issues with what gets stored in my array that is going to be printed.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef char *string;
typedef char *alpha;
int main(void)
{
string morse[4]={".-", "-...","----.", ".."};
string alpha[4]={"A", "B", "9", "I"};
char prntArr[50];
char *input;
char *hold;
input = malloc(200);
hold = malloc(50);
int i=0;
int j=0;
int ret;
int x;
int w=0;
int z=0;
printf("please enter a string\n");
scanf("%[^\n]",input);
do{
if (input[i] !=' ')
{
hold[j] = input[i];
j++;
}
else
{
hold[j]='\0';
for (x=0;x<4;x++)
{
printf("value of x %d\n",x);
ret = strcmp(morse[x], hold);
if (ret==0)
{
printf("%s\n",alpha[x]);
prntArr[w]=*hold;
w++;
x=4;
}
else
{
ret=1;
printf("invalid Morse code!");
}
}
j = 0;
}
i++;
}while(input[i] !='\0');
for (z=0;z<50;z++)
{
printf("%c",prntArr[z]);
}
return 0;
free(input);
}
The problem you asked about is caused by the way prntArr is used in the program. It really should be an array of character pointers into the alpha array. Instead, it's manipulated as an array of characters into which the first character of each morse code element is stored. And when it's printed, the variable that tracks how much of the array is used is simply ignored.
Another problem is that your code uses spaces to break the codes but there won't necessarily be a space at the end of the line so a code might get missed. In the program below, I switched out scanf() for fgets() which leaves a newline character on the end of the input which we can use, like space, to indicate the end of a code.
Other problems: you print the invalid Morse code message at the wrong point in the code and you print it to stdout instead of stderr; you remember to free input but forget to free hold; you put code after return that never gets called.
Below is a rework of your code that addresses the above problems along with some style issues:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main(void)
{
char *morse[] = {".-", "-...", "----.", ".."};
char *alpha[] = {"A" , "B" , "9" , "I" };
char *print_array[50];
int print_array_index = 0;
char hold[50];
int hold_index = 0;
char input[200];
int i = 0;
printf("please enter a string: ");
fgets(input, sizeof(input), stdin);
while (input[i] !='\0') {
if (input[i] ==' ' || input[i] == '\n')
{
hold[hold_index] = '\0';
bool found = false;
for (int x = 0; x < sizeof(morse) / sizeof(char *); x++)
{
if (strcmp(morse[x], hold) == 0)
{
print_array[print_array_index++] = alpha[x];
found = true;
break;
}
}
if (!found)
{
fprintf(stderr, "invalid Morse code: %s\n", hold);
}
hold_index = 0;
}
else
{
hold[hold_index++] = input[i];
}
i++;
}
for (int x = 0; x < print_array_index; x++)
{
printf("%s ", print_array[x]);
}
printf("\n");
return 0;
}
SAMPLE RUNS
> ./a.out
please enter a string: ----. -... .- ..
9 B A I
>
> ./a.out
please enter a string: .- --- ..
invalid Morse code: ---
A I
>

How to split a string into int[3]

I have a string, like "101 1 13" and I need to split it to a int aux[3] --> resulting in aux[0] = 101, aux[1] = 1 and aux[2] = 13 (in this case). How can
I do that?
In the example of the code below I get op as a String and want to get the value of the INTs in there. Each int is divided in the string by a white space(" ").
Another detail: I need the code to compile with flag -std=c99, so the answer that was accepted would not work.
#include <stdio.h>
#include <stdlib.h>
//example of str = "101 1 14" (char *)
// example of output = {101, 1, 14}(int *)
int* stoi(char *str) {
// function to split str into 3 ints
}
int main() {
char op[10];
int num[3];
scanf("%s\n", op);
num = stoi(op);
printf("%d %d %d", num[0], num[1], num[2]);
return 0;
}
First you need to tokenize your input (break apart the input into distinct elements). Then you need to parse/integerize the individual tokens by converting them from strings to the desired format.
Sample Code
#include <stdio.h>
#include <string.h>
#define BUF_LEN (64)
int main(void)
{
char buf[BUF_LEN] = { 0 };
char* rest = buf;
char* token;
int i = 0;
int iArr[100] = { 0 };
if ( fgets(buf, BUF_LEN, stdin) != NULL )
{
strtok(buf, "\n"); // Remove newline from input buffer in case we want to call fgets() again.
while ( (token = strtok_r(rest, " ", &rest)) != NULL )
{
iArr[i] = strtol(token, NULL, 10);
printf("Token %d:[%d].\n", i, iArr[i]);
i++;
}
}
return 0;
}
Sample Run
1231 12312 312 1232 1312
Token 0:[1231].
Token 1:[12312].
Token 2:[312].
Token 3:[1232].
Token 4:[1312].
Try to replace your code by following code.
The new code works only if input contains only single space between integers.
Your code:
while(op[cont] != '\0') {
for(i = 0; op[cont] != ' '; i++, cont++) {
num[i] += op[cont];
}
printf("num[i] = %d\n", num[i]);
}
New code:
while(op[cont] != '\0')
{
if(op[cont] != ' ')
num[i] = num[i]*10 + (op[cont]- '0');
else
i++;
cont++;
}
See this example of how to do that:
char string [10] = "101 1 666"
int v [3], n=0, j=0;
int tam = strlen(string);
int current_Len = 0;
for(i=0; i<tam; i++){
//32 = ascii for White space
if(string[i] != 32){
n = n*10 + string[i] - '0';
current_len++;
} else if (current_len > 0){
v[j++] = n;
current_len = 0;
n=0;
}
}
if (current_len > 0){
v[j++] = n;
}
This answer is assuming you know how much integers your string contain at the time of writing your code. It also uses specific clang/gcc extension (typeof) and may not be portable. But it may be helpful to someone (I mainly wrote it because I had nothing good to do).
#include <stdio.h>
#include <string.h>
struct {int _[3];} strToInt3(const char (*pStr)[])
{
int result[3] = {0}, *pr = result;
for(register const char *p = *pStr; *p; ++p)
{
if(*p == ' ') ++pr;
else
*pr *= 10,
*pr += *p - '0';
}
return *(__typeof__(strToInt3(0)) *)result;
}
int main()
{
char op[10];
int num[3];
scanf("%10[^\n]", op),
//memcpy(num, strToInt3(op)._, sizeof(num));
//or
*(__typeof__(strToInt3(0)) *)num = strToInt3(op);
printf("%d %d %d", num[0], num[1], num[2]);
}
I've commented the copying of returned array using memcpy and added a structure assignment. Although both must be valid (not standard I guess but working in most cases) I prefer the second option (and maybe some compiler optimizers will).
Also I assume ASCII character set for chars.
I found an easier approach to the problem. I insert a scanf, that don't catch the space blanket and convert it using atoi. As it is just 3 ints it doesn't become so bad to use this simple, repetitive way of catching the values. And it work with the -std=c99 flag, that I needed to use.
scanf("%s[^ ]\n", op);
num[0] = atoi(op);
scanf("%s[^ ]\n", op);
num[1] = atoi(op);
scanf("%s[^ ]\n", op);
num[2] = atoi(op);
printf("%d\n", num[0]);
printf("%d\n", num[1]);
printf("%d\n", num[2]);

C: How can I read unkown number of integers inside parenthesis from input?

It's quite bothering when reading unknown number of integers within a pair of parenthesis.
For example:
(1, 2, 3)
But We don't how many integers there are.
Rather than reading them entirely as a string, can anyone have any other ideas to fix that?
Many thanks.
It is terribly unclear what you really want from the posted question. But if you're talking about variable length arguments to a function, then:
Look into Variable arguments in C.
If you are talking about reading unknown no. of integers from input buffer, then you'll have to make your own function to read character by character, parsing the input for numbers, parenthesis and commas: A basic parser to do that is below(note, its not tested and can contain bugs) - understand and modify it accordingly. You can read in any no. of integers with this program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef enum { START, OPAREN, CPAREN, COMMA, DIGIT, EOF_S,UNKNOWN }Token;
int c;
unsigned char state = 0;
int numbers[100];
Token getToken(FILE *f)
{
while(isspace(c = fgetc(f)));
if(c == EOF) return EOF_S;
if(c == '(') return OPAREN;
if(c == ',') return COMMA;
if(c == ')') return CPAREN;
if(isdigit(c)) return DIGIT;
return UNKNOWN;
}
int getNumber(FILE *f)
{
int returnNumber = 0;
Token tok = START;
while(tok != DIGIT){
tok = getToken(f);
if(tok == UNKNOWN){ state = 1; return 0x0FFFFFFF;}
if(tok == EOF_S) { state = 2; return 0x0FFFFFFF;}
}
if(tok == DIGIT){
while(tok == DIGIT){
returnNumber = returnNumber * 10 + (c - '0');
tok =getToken(f);
}
}
return returnNumber;
}
int getNumbers(FILE *f, int *numbers_0)
{
int number;
int no_counter = 0;
while(((number = getNumber(f)) != 0x0FFFFFFF) && (state == 0)){
numbers_0[no_counter++] = number;
}
return no_counter; //returns no. of numbers between ( and ), separated by ','
}
int main(int argc, char *argv[])
{
int no, i;
no = getNumbers(stdin,numbers);
if(no > 100) no = 100;
for(i = 0; i < no; i++){
printf("%d\n",numbers[i]);
}
return 0;
}
Here after a simple C code to do it
#include <stdio.h>
int main(int argc, char **argv)
{
int x; char c='\0';
scanf("%*[(]");
while (c != ')' && scanf("%d %c", &x, &c)==2){
if (c!=',' && c != ')') {
printf ("format error in the input\n");
break;
}
printf("Number: %d\n", x);
}
}
If your input stream is stdin then use scanf as indicated in the above code
If your input stream is a file then use fscanf
if u need only read ( and processing right now) u can
read char C until C=='('
read char C if it space/tab/CR/LF continue step 2 else step 3
if C==')' End of reading list
so if u here c is a digit so u can getback char( use ungetc(C,stdin) ) and reread all number as integer .here u can opirate with intger as u wish. continue to 2.
If list is syntax correct above algo enogh else add where read C test on EOF and on step 4 test on alpha.
I think u can rewrite algo using C without goto.
I hope you are looking for a function implementation with variable arguments, below snippet will help you.
int add(int *total, int count, ...)
{
int i = 0;
va_list numbers;
va_start(numbers, count);
for (i = 0; i < count; i++)
{
*total += va_arg(numbers, int);
}
va_end(numbers);
}
You can call this function like
...
int result = 0;
add(&result, 3, 10, 20, 30);
...

Resources