I am trying to remove the spaces from my array "secuencia", the users give me this entry:
"1 2 3 4 5 6 7 8 9"
I want to remove the spaces, and save it in another array for later. Then, convert to integer with "ATOI" like I do with the arrays "palancas" and "palancaroja". Those two arrays only contained one number, so I had no problem with them.
please help me... I am programming in ANSI C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char * argv[])
{
char palancas [20000];
int palancai;
char palancaroja[10];
int palancarojai;
char secuencia[20000];
char temp[20000];
int j = 0;
printf("Dame El Numero De Palancas:");
fgets(palancas, 20000, stdin);
printf("Dame La Posision De La Palanca Roja:");
fgets(palancaroja, 10, stdin);
palancai = atoi(palancas);
palancarojai = atoi(palancaroja);
printf("Dame La cadena");
fgets(secuencia, 20000, stdin);
for (int i = 0; i < palancai; i++) {
if (secuencia [i] != ' ') {
temp [i] = secuencia [i];
printf("%s", temp);
}
}
}
This is the simplest way to remove spaces from a string.
char *SourcePtr = secuencia;
char *TargetPtr = SourcePtr;
while (*SourcePtr != 0)
{
if (*SourcePtr != ' ')
{
*TargetPtr = *SourcePtr;
TargetPtr += 1;
}
SourcePtr += 1;
}
*TargetPtr = 0;
Translated version of critical section
for (int i = 0; i < length; i++) {
if (source[i] != ' ') {
temp[i] = source[i];
printf("%s", temp);
}
}
This code copies every character from the array source to the array temp, but simply skips spaces. So if temp is initialized with XXXXX and source is A B C, then temp is AXBXC after the execution of the loop.
You have use two indexes (see other answer)
#include <stdio.h>
//copy to d from s removed space
void remove_space(char *d, const char *s){
for(;*s;++s){
if(*s != ' ')
*d++ = *s;
}
*d = *s;
}
int main(){//DEMO
char secuencia[] = "1 2 3 4 5 6 7 8 9";
char temp[sizeof(secuencia)];
remove_space(temp, secuencia);
puts(temp);//123456789
return 0;
}
You could use strtok and tokenize the string that you get with the delimiter string being " ".
In other words:
char * tok;
int i = 0;
tok = strtok(secuencia, " ");
while(tok != NULL){
temp[i] = tok[0];
i++;
tok = strtok(NULL, " ");
}
This would only work if it's guaranteed that it's a single digit between each space though. Another way to copy it would be to use another loop, cycling through strtok until '\0' is reached, or using strcpy.
first I think that your for loop is looking at the wrong variable. you are trying to loop on palancai where really you want to loop on secuencia.
Below you can find a function that will parse your int.
int MyIntParse(char* str)
{
int iReturn = 0;
for(int i=0;i<20000;++i)
{
iReturn *=10;
switch(str[i])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
iReturn = iReturn + (str[i] - '0');
break;
}
}
return iReturn;
}
Related
I have a program that separates words by spaces. I need to count which words in the text contain 4 different vowels. It didn't seem complicated, until I realized that I know how to save the divided words of the function (strtok) that returns the separated words, and of course, I can't count a single word because the function only prints. I don't know how to save the word individually to calculate how many vowels it contains and continue with the other words, one by one.
#include <stdio.h>
#include <string.h>
#define MAX 100
int main() {
char phase[MAX];
char temp [50];
char delim[] = " ";
printf("Ingrese un texto corto: ");
gets(phase); //Short text with spaces
printf("\n");
for (i = 0; x < phase[x] != '\0'; ++x) {
if (phase[x] == ' ' || phase[x] == '\t' || phase[x] == '\v') {
//Detect space.
}
}
char *ptr = strtok(phase, delim);
while (ptr != NULL) {
printf("%s\n", ptr); //I need to keep all the words separate.
ptr = strtok(NULL, delim);
}
return 0;
}
Result:
Ingrese un texto corto: Ana come en el refrigerador.
Ana
come
en
el
refrigerador.
I believe this code will solve the task. It's tempting to use strtok() again to search for vowels, but that would erase any information about word bounds from strtok's internal memory. So, instead, use strpbrk() (docs and more docs)
#include <stdio.h>
#include <string.h>
#define MAX 100
int main() {
char text[MAX];
// all isspace() characters for "C" locale
char delimiters[] = " \t\n\v\f\r";
char vowels[] = "aeiou";
printf("Input a string of text: ");
// replaced unsafe gets() with more safe fgets()
fgets(text, sizeof(text), stdin);
char* word = strtok(text, delimiters);
while (word != NULL) {
// strpbrk() does roughly the same thing as strtok(), but it doesn't
// modify a string nor does it remember anything on future calls
char* ptr_to_vowel = word;
int count = 0;
while (NULL != (ptr_to_vowel = strpbrk(ptr_to_vowel, vowels))) {
count++;
// otherwise we'd stay on the same vowel
ptr_to_vowel++;
}
printf("found %d vowels in %s\n", count, word);
word = strtok(NULL, delimiters);
}
return 0;
}
A few issues:
The for loop for counting spaces is incorrect.
We should have a separate function to count vowels.
Never use gets (use fgets instead).
The code did not preserve the original buffer as the code comments suggested.
I need to count which words in the text contain 4 different vowels.
So, we can only count unique vowels in a word (e.g.):
fleece has only 1 unique vowel and not 3.
great has 2 vowels
greet has 1 vowel
incombustible has 4 [unique] vowels and not 5.
It's not totally clear, but I interpret this to mean that a candidate word has at least 4 unique vowels (i.e. it could have 5)
I had to refactor quite a bit of the code. It is annotated:
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <ctype.h>
#define MAX 100
// vcount -- count _unique_ vowels
// RETURNS: number of _unique_ vowels
int
vcount(const char *str)
{
const char *vowels = "aeiou";
int vfreq[5] = { 0 };
int vsum = 0;
// loop through all chars in string
for (int chr = *str++; chr != 0; chr = *str++) {
// get lower case
chr = tolower((unsigned char) chr);
// is it a vowel?
const char *vptr = strchr(vowels,chr);
if (vptr == NULL)
continue;
// get index into frequency table
ptrdiff_t vidx = vptr - vowels;
// have we seen it before?
if (vfreq[vidx])
continue;
// mark as already seen
vfreq[vidx] = 1;
// count new unique vowel
++vsum;
}
return vsum;
}
int
main(void)
{
char phrase[MAX];
char temp[MAX];
const char *delim = " \t\v";
printf("Ingrese un texto corto: ");
// Short text with spaces
// NOTE/BUG: _never_ use gets
#if 0
gets(phrase);
#else
fgets(phrase,sizeof(phrase),stdin);
#endif
printf("\n");
// NOTE/BUG: loop condition is incorrect
#if 0
for (i = 0; x < phrase[x] != '\0'; ++x) {
if (phrase[x] == ' ' || phrase[x] == '\t' || phrase[x] == '\v') {
// Detect space.
}
}
#else
int space_count = 0;
for (int i = 0; phrase[i] != '\0'; ++i) {
switch (phrase[i]) {
case ' ':
case '\t':
case '\v':
++space_count;
break;
}
}
printf("Spaces: %d\n",space_count);
#endif
// I need to keep all the words separate.
#if 0
char *ptr = strtok(phrase, delim);
#else
strcpy(temp,phrase);
char *ptr = strtok(temp, delim);
#endif
while (ptr != NULL) {
#if 0
printf("%s\n", ptr);
#else
printf("%s -- has enough vowels: %s\n",
ptr,(vcount(ptr) >= 4) ? "Yes" : "No");
#endif
ptr = strtok(NULL, delim);
}
return 0;
}
In the above code, I used cpp conditionals to denote old vs new code:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
For the input:
Ana come en el refrigerador.
Here is the program output:
Ingrese un texto corto:
Spaces: 4
Ana -- has enough vowels: No
come -- has enough vowels: No
en -- has enough vowels: No
el -- has enough vowels: No
refrigerador. -- has enough vowels: Yes
Instead of splitting words and then count vowels inside them, you can count vowels and upon a delimiter, check the vowel count and reset the count. This way, you do not need to modify the string. You actually do not even need an array to store the string: you can just read one byte at a time.
Here is a modified version:
#include <stdio.h>
int main() {
int mask = 0;
int vowels = 0;
int matches = 0;
int done = 0;
printf("Ingrese un texto: ");
while (!done) {
switch (getchar()) {
case EOF:
case '\n':
if (vowels >= 4)
matches++;
vowels = mask = 0;
done = 1;
break;
case ' ':
case '\t':
case '\n':
case '\v':
case '\f':
case '\r':
if (vowels >= 4)
matches++;
vowels = mask = 0;
break;
case 'a':
case 'A':
if (!(mask & 1)) {
mask |= 1;
vowels++;
}
break;
case 'e':
case 'E':
if (!(mask & 2)) {
mask |= 2;
vowels++;
}
break;
case 'i':
case 'I':
if (!(mask & 4)) {
mask |= 4;
vowels++;
}
break;
case 'o':
case 'O':
if (!(mask & 8)) {
mask |= 8;
vowels++;
}
break;
case 'u':
case 'U':
if (!(mask & 16)) {
mask |= 16;
vowels++;
}
break;
}
}
printf("%d\n", matches);
return 0;
}
Here is an alternative without a switch statement:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main() {
int mask = 0;
int vowels = 0;
int matches = 0;
const char *vowels = "aAeEiIoOuU";
printf("Ingrese un texto: ");
while (!done) {
int c = getchar();
if (c == EOF || isspace(c)) {
if (vowels >= 4)
matches++;
vowels = mask = 0;
if (c == '\n' || c == EOF)
done = 1;
} else {
char *p = memchr(vowels, c, 10);
if (p != NULL) {
int bit = 1 << ((p - vowels) / 2);
if (!(mask & bit)) {
mask |= bit;
vowels++;
}
}
}
}
printf("%d\n", matches);
return 0;
}
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.'
I made a program which receives from 2 till 5 strings and concatenate all together using a variable arguments function.
So far the program works OK, but it always show at the end 3 random characters before showing the complete string.
For example:
Please insert number of strings: 3
string 1: car
string 2: bike
string 3: plane
Full string:
=$>carbikeplane
I have made several tweaks to the program trying to find the reason and fix it, however I always get the same result.
The full program is showed below.
Few comments about the program:
I am printing the strings in different parts of the programs because I was trying to locate where the problem was coming. So some of the printf() functions may not have sense.
The main function seems to be fine, the problem is in the function defined later.
NOTE: I'm still learning C, so there may be some code that can/might be creating undefined behavior, if there is, I would appreciate if you can point those out.
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
char *function(int num, ...);
int main(void)
{
char line1[80] = " ", line2[80] = " ", line3[80] = " ", line4[80] = " ", line5[80] = " ";
int count = 0, count2;
char *newStr;
int i;
int status;
do {
fflush(stdin);
printf("\nPlease select the number of strings (max. 5): ");
scanf("%d", &count);
}while(count < 2 && count > 5);
count2 = count;
fflush(stdin);
status = 1;
for( i = 1 ; count > 0; count--, i++)
{
switch(status)
{
case 1:
{
printf("\nInput string[%d]: ", i);
gets(line1);
status = 2;
break;
}
case 2:
{
printf("\nInput string[%d]: ", i);
gets(line2);
status = 3;
break;
}
case 3:
{
printf("\nInput string[%d]: ", i);
gets(line3);
status = 4;
break;
}
case 4:
{
printf("\nInput string[%d]: ", i);
gets(line4);
status = 5;
break;
}
case 5:
{
printf("\nInput string[%d]: ", i);
gets(line5);
status = 6;
break;
}
}
}
printf("\n%s\n%s\n%s\n%s\n%s\n", line1, line2, line3, line4, line5);
/*call the function of variable arguments*/
/*memory allocation of newstr*/
newStr = (char *)malloc(420*sizeof(char) +1);
switch(count2)
{
case 2:
{
newStr = function(2, line1, line2);
break;
}
case 3:
{
newStr = function(3, line1, line2, line3);
break;
}
case 4:
{
newStr = function(4, line1, line2, line3, line4);
break;
}
case 5:
{
newStr = function(5, line1, line2, line3, line4, line5);
}
}
printf("\nThe final string is: \n");
printf("%s", newStr);
return 0;
}
char *function(int num, ...)
{
va_list arg_ptr;
int b;
char *string;
char *curstr;
va_start(arg_ptr, num); /*initialize the arg_ptr*/
string = (char *)malloc(420*sizeof(char) + 1);
*string = " ";
for(b=0; b < num; b++)
{
curstr = va_arg(arg_ptr, char * );
string = strcat(string,curstr);
}
printf("\n%s", string);
va_end(arg_ptr);
return string;
}
The real problem is that you can compile the line: *string = " "; This is not valid anymore and should not compile. Assumingly you put that line there to initialize your string to have an initial value. But this can easily be solved by allocating the string like this:
string = calloc(420, sizeof(char));
ie: use calloc which sets the memory to zero. This way you have a valid string which can be used by strcat.
I'm not telling you to do not use gets or fflush because it is obvious that this is a home assignment and the suggested fgets has its own problems when dealing with the input string. Certainly if you will use gets in production code someone will kick you at that time.
And about casting the return value of malloc again, it's a two sided sword. If you know for sure that you will compile your project as a C project (ie: filename ends in .c and you use gcc to compile) then yes. Do not cast. However in other circumstances, such as naming the files .cpp or compiling with g++ .... well. You will get the error: error: invalid conversion from ‘void*’ to ‘char*’ without the cast. And I have the feeling that at a beginner level, while doing home assignments for school you more or less concentrate on making your code to compile and run, rather than stick to be pedantic. However for the future, it is recommended that you will be pedantic.
Here is a quick and dirty way to concatenate as many strings as the user wants to enter. Simply press ctrl+d when done to end input:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *concat (const char *str1, const char *str2) {
size_t len1 = strlen (str1); /* get lenghts */
size_t len2 = strlen (str2);
char * s = malloc (len1 + len2 + 2); /* allocate s and concat with ' ' */
memcpy (s, str1, len1);
s [len1] = ' ';
memcpy(s + len1 + 1, str2, len2); /* does not include terminating null */
s [len1 + len2 + 1] = '\0'; /* force null termination */
return s;
}
int main (void) {
char *line = NULL; /* pointer to use with getline () */
ssize_t read = 0;
size_t n = 0;
int cnt = 0;
char *str;
printf ("\nEnter a line of text to concatenate (or ctrl+d to quit)\n\n");
while (printf (" input: ") && (read = getline (&line, &n, stdin)) != -1) {
if (line[read-1] == '\n') { /* strip newline */
line[read-1] = 0;
read--;
}
if (cnt == 0) /* if more than 1 word, concat */
str = strdup (line);
else
str = concat (str, line);
cnt++;
}
printf ("\n\n Concatenated string: %s\n\n", str);
return 0;
}
output:
$ ./bin/concat
Enter a line of text to concatenate (or ctrl+d to quit)
input: my dog
input: has lots of fleas
input: my cat
input: has some too.
input:
Concatenated string: my dog has lots of fleas my cat has some too.
This is the modified code working fine
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#include <stdarg.h>
char *function(int num, ...);
int main(void)
{
char line1[80] = " ", line2[80] = " ", line3[80] = " ", line4[80] = " ", line5[80] = " ";
int count = 0, count2;
char *newStr;
int i;
int status;
do {
fflush(stdin);
printf("\nPlease select the number of strings (max. 5): ");
scanf("%d", &count);
}while(count < 2 && count > 5);
count2 = count;
fflush(stdin);
status = 1;
for( i = 1 ; count > 0; count--, i++)
{
switch(status)
{
case 1:
{
printf("\nInput string[%d]: ", i);
gets(line1);
status = 2;
break;
}
case 2:
{
printf("\nInput string[%d]: ", i);
gets(line2);
status = 3;
break;
}
case 3:
{
printf("\nInput string[%d]: ", i);
gets(line3);
status = 4;
break;
}
case 4:
{
printf("\nInput string[%d]: ", i);
gets(line4);
status = 5;
break;
}
case 5:
{
printf("\nInput string[%d]: ", i);
gets(line5);
status = 6;
break;
}
}
}
printf("\n%s\n%s\n%s\n%s\n%s\n", line1, line2, line3, line4, line5);
/*call the function of variable arguments*/
/*memory allocation of newstr*/
newStr = (char *)malloc(420*sizeof(char) +1);
switch(count2)
{
case 2:
{
newStr = function(2, line1, line2);
break;
}
case 3:
{
newStr = function(3, line1, line2, line3);
break;
}
case 4:
{
newStr = function(4, line1, line2, line3, line4);
break;
}
case 5:
{
newStr = function(5, line1, line2, line3, line4, line5);
}
}
printf("\nThe final string is: \n");
printf("%s", newStr);
return 0;
}
char *function(int num, ...)
{
va_list arg_ptr;
int b;
char *string;
char *curstr;
va_start(arg_ptr, num); /*initialize the arg_ptr*/
string = (char *)malloc(420*sizeof(char) + 1);
//*string = " ";
for(b=0; b < num; b++)
{
curstr = va_arg(arg_ptr, char * );
string = strcat(string,curstr);
}
printf("\n%s", string);
va_end(arg_ptr);
return string;
}
Just included stdlib and commented *string
Have a nice day
Length of your code is proportional to max strings user can enter. That doesn't sound good, right? (what if someone in the future will ask you to change it to allow user to enter 10 strings? 20? 100???).
In such cases usually in help come arrays - instead of having 5 different variables just use an array of them:
So change:
char line1[80], line2[80], line3[80], line4[80], line5[80];
to:
char lines[5][80];
So when in need of setting for e.g. second string, you can get it through:
char* line2 = lines[1]; \\ remember about indexes starting from 0,
\\ so second element has index 1
So now instead of 5 switch cases you can go with:
for( i = 1 ; count > 0; count--, i++)
{
printf("\nInput string[%d]: ", i);
fgets(lines[i], 80, stdin);
}
Moreover you don't need variable arguments function, as you can just pass array and it's size:
char *function(int array_elements, char ** array);
//Usage:
concatenated_string = function(5, lines);
Also it's good practice to put all const values into variables (so when changing max amount of string user can enter, you need to change only one place).
const int MAX_STRINGS = 5;
const int MAX_STRING_LENGTH = 80;
Now comes the real problem:
string = (char *)malloc(420*sizeof(char) + 1);
*string = " ";
Why would you allocate 420 bytes? What if user enters only one string - what do you need the rest 340 bytes for?
To get the length of concatenate strings, iterate through lines (from 0 to array_size), get lengths of lines (with strlen), sum them together and add 1 for trailing '\0'. Now you won't have any unnecessary memory allocated.
Next - *string = " "; should not compile as *string is a char and " " i a string (char *). Do *string = '\0' instead or call calloc instead of malloc.
I have a char* like this "1 10 14 16"
I want to split it to integer array like 1,10,14,16...
how i do that?
I suggest using strtol in a loop, using explicitly its endptr argument, something like:
char* pc = input_string;
char* end = NULL;
while (*pc) {
long l = strtol (pc, &end, 0);
if (end == pc) break;
do_something_useful_with_the_number (l);
pc = end;
}
if you want to accumulate all the numbers in an array, replace do_something_useful_with_the_number (l); with code growing that array (probably using malloc and/or realloc ...)
I would use strtok() like this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
char string[] = "1 10 14 16",
*next = NULL;
int number[10] = {0},
noOfNumbers = 0,
i = 0;
next = strtok(string, " "); /* first call must have the string and delimiters */
while ( next != NULL ) {
number[noOfNumbers++] = atoi(next);
next = strtok(NULL, " "); /* second call only the delimiters */
}
for ( i = 0; i < noOfNumbers; i++ ) {
printf("number[%d] = %d\n", i, number[i]);
}
return 0;
}
How you ensure the array of ints is big enough is left to you.
Use strtok to separate the numbers and then use atoi on each of them to convert them to integers.
http://www.elook.org/programming/c/strtok.html
int output[4];
char *input_string = "1 10 14 16";
sscanf(input_string, "%d %d %d %d", &output[0], &output[1], &output[2], &output[3]);
printf(" OUTPUT : %d %d %d %d\n", output[0], output[1], output[2], output[3]);
Above code should work
Regards
1 you will have to a strtok to get one number string at a time.
2 Then you have todo atoi to convert a number string into an int.
This needs to be done till the loop condition of strtok returns a valid string
#include <stdio.h>
///i is count *input_string[] times
///j is count temp[] times
int main() {
int i,j=0,num=0,*ptr,output;
char temp[9]={'\0'};
char *input_string[] = {"1 10 14 16 20 31 34 67 23 45 23"};
for(i=0;*(*(input_string+0)+i)!='\0';)
{
switch(*(*(input_string+0)+i))
{
case ' ':i++;break;
case '1':case '2':case '3':
case '4':case '5':case '6':
case '7':case '8':case '9':
case '0':
j=0;
while(*(*(input_string+0)+i) != ' ' || j>9 )
{
temp[j]=*(*(input_string+0)+i);
i++;j++;
}
j++;
temp[j]='\0';
output=atoi(temp);
ptr=malloc( sizeof(int) );
ptr=&output;
printf("%d ",*ptr);
break;
}
}
return 0;
}
I made small modifications.I updated the malloc (); function.May I ask whether the condition?Thank you!
#include <stdio.h>
///i is count *input_string[] times
///j is count temp[] times
///num is count output[] times
int main() {
int i,j=0,num=0;
int output[4];
char temp[9]={'\0'};
char *input_string[] = {"1 10 14 16"};
for(i=0;*(*(input_string+0)+i)!='\0';)
{
switch(*(*(input_string+0)+i))
{
case ' ':i++;break;
case '1':case '2':case '3':
case '4':case '5':case '6':
case '7':case '8':case '9':
case '0':
j=0;
while(*(*(input_string+0)+i) != ' ' || j>9 )
{
temp[j]=*(*(input_string+0)+i);
i++;j++;
}
j++;
temp[j]='\0';
output[num]=atoi(temp);
num++;
break;
}
}
for(i=0;i<4;i++)///print number
printf("%d ",output[i]);
return 0;
}
///*(*(input_string+0)+i) you can see is e.g char input_string[][];
When two vowels come one after another then the count should increment.But i dont know why its incrementing it more than that.
#include<stdio.h>
#include<conio.h>
void main(void)
{
int i,j,count=0;
char string[80];
printf("Enter a string:\n");
gets(string);
for(i=0; ;i++)
{
if(string[i]=='\0')
break;
if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
if(string[i+1]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
count++;
}
}
printf("%d",count);
getch();
}
Looks like you have a typo here, your code:
if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
if(string[i+1]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
count++;
}
Notice the second if statement there, everything except the first condition is checking string[i] instead of string[i+1]. So if you have 'A' in string[i], then this will increment count no matter what is in string[i+1].
You want:
if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
if(string[i+1]=='a'||string[i+1]=='A'||string[i+1]=='e'||string[i+1]=='E'||string[i+1]=='i'||string[i+1]=='I'||string[i+1]=='o'||string[i+1]=='O'||string[i+1]=='u'||string[i+1]=='U')
count++;
}
I also recommend you look up the function tolower which will lower-case a character, meaning you need to do less comparisons which will make this code much easier to read and maintain. Also you might consider using a switch or any array hereand probably writing a helper function.
I guess I just can't stand this code as it is, here's a better version:
int is_vowel(char ch)
{
switch (tolower(ch))
{
case 'a': case 'e': case 'i': case 'o': case 'u':
return 1;
default:
return 0;
}
}
And then make your if statement:
if (is_vowel(string[i]) && is_vowel(string[i+1]))
count++;
See, much cleaner and easier to read, don't you think?
You also have a buffer overflow:
gets(string);
And the following is bad style:
for(i=0; ;i++)
{
if(string[i]=='\0')
break;
should be
for(i=0; string[i]!='\0';i++)
For once, be as lazy as you can. If you have to repeat a portion of code, ask yourself if you can't do it without repeating.
I would have gone for that :
#include <stdio.h>
#include <string.h>
#include <ctype.h>
const size_t MAX_LENGTH = 100;
//Counts the occurrences of two consecutive same characters
//in a string, without case
size_t cnt_doubled(char const * const str, int c) {
size_t ret = 0;
//A pointer browses the string until terminating char and
//increments ret if the pointed char is the one seeked
//two chars in a row
for(char const *p = str ; *p != '\0' ; ++p) {
ret += tolower(*p) == tolower(c) && tolower(*(p+1)) == tolower(c);
}
return ret;
}
//Explicit...
size_t cnt_doubled_vowels(char *str) {
char const *vowels = "aeiouy";
//A pointer browses the vowels and takes into account
//the occurrences in the string of every char pointed
size_t n_vowels = 0;
for(char const *p = vowels ; *p != '\0' ; ++p) {
n_vowels += cnt_doubled(str, *p);
}
return n_vowels;
}
int main(void) {
//fgets returns a string terminated by a newline char (before
//terminating char of course) but in your case it doesn't
//matter
char string[MAX_LENGTH] = "";
fgets(string, MAX_LENGTH, stdin);
printf("N : %d", cnt_doubled_vowels(string));
return 0;
}