Printing the digits present in the string.
Suppose i have an input like this
Input: {1,32,33,41,59}
The output should look like this
Output: 1 32 33 41 59
My code is
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char input[200],words[10][10];
int length=0,i=0,j=0,k=0,t;
fgets(input,200,stdin);
//counting the length of str
while(input[length] != '\0')
{
length++;
}
for(i=1;i<=length;i++)
{
if(input[i] == ',' || input[i] == '}')
{
words[j][k] = '\0';
j++;
k=0;
}
else
{
words[j][k] = input[i];
k++;
}
}
int temp[j];
for(i=0;i<j-1;i++)
{
temp[i] = atoi(words[i]);
printf("%d\n",temp[i]);
}
return 0;
}
My code just prints the first digit in the string. I can't figure out why.
Use j instead of j-1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char input[200],words[10][10];
int length=0,i=0,j=0,k=0,t;
fgets(input,200,stdin);
//counting the length of str
while(input[length] != '\0')
{
length++;
}
for(i=1;i<=length;i++)
{
if(input[i] == ',' || input[i] == '}')
{
words[j][k] = '\0';
j++;
k=0;
}
else
{
words[j][k] = input[i];
k++;
}
}
int temp[j];
for(i=0;i<j;i++)
{
temp[i] = atoi(words[i]);
printf("%d\n",temp[i]);
}
return 0;
}
I made a few edits to your code and believe I got it working the way you want. I commented the changes, please look below.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char input[200],words[10][10];
int length=0,i=0,j=0,k=0,t;
fgets(input,200,stdin);
while(input[length] != '\0')
{
length++;
}
for(i=1;i<=length;i++)
{
if(input[i] == ',' || input[i] == '}')
{
words[j][k] = '\0';
j++;
k=0;
}
else
{
words[j][k] = input[i];
k++;
}
}
int temp[j];
//Iterate through all elements in the array
//0 ---> j-1 is j elements
for(i=0;i < j ;i++)
{
temp[i] = atoi(words[i]);
//print on the same line
printf("%d ",temp[i]);
}
//newline here
printf("\n");
return 0;
}
Your approach is too complicated and as such has bugs.
There is no need to define a character two-dimensional array to output stored in a string numbers. It is enough from the very beginning to use a standard function like for example strtoull.
Here you are.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
enum { N = 200 };
char input[N];
while ( 1 )
{
printf( "Input: " );
if ( !fgets( input, sizeof( input ), stdin ) || input[0] == '\n') break;
for ( char *p = input; *p; )
{
if ( isdigit( ( unsigned char )*p ) )
{
char *endptr;
unsigned long long int num = strtoull( p, &endptr, 10 );
printf( "%llu\n", num );
p = endptr;
}
else
{
++p;
}
}
}
return 0;
}
The program output might look like
Input: {1,32,33,41,59}
1
32
33
41
59
Input:
I suggest you this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const char *const s = ",";
int main()
{
char input[200], *ptri, *ptr;
fgets(input, 200, stdin);
ptr = input;
while (*ptr != '{' && *ptr != '\0')
ptr++;
if (*ptr == '\0') {
return -1; /* not found */
}
ptr++;
ptri = ptr;
while (*ptr != '}' && *ptr != '\0')
ptr++;
if (*ptr == '\0') {
return -1; /* not found */
}
*ptr = '\0';
ptr = strtok(ptri, s);
while (ptr != NULL) {
printf("%s ", ptr);
ptr = strtok(NULL, s);
}
printf("\n");
return 0;
}
Related
I need to write a function that will count words in a string. For the
purpose of this assignment, a "word" is defined to be a sequence
of non-null, non-whitespace characters, separated from other words by
whitespace.
This is what I have so far:
int words(const char sentence[ ]);
int i, length=0, count=0, last=0;
length= strlen(sentence);
for (i=0, i<length, i++)
if (sentence[i] != ' ')
if (last=0)
count++;
else
last=1;
else
last=0;
return count;
I am not sure if it works or not because I can't test it until my whole program is finished and I am not sure it will work, is there a better way of writing this function?
You needed
int words(const char sentence[])
{
}
(note braces).
For loops go with ; instead of ,.
Without any disclaimer, here's what I'd have written:
See it live http://ideone.com/uNgPL
#include <string.h>
#include <stdio.h>
int words(const char sentence[ ])
{
int counted = 0; // result
// state:
const char* it = sentence;
int inword = 0;
do switch(*it) {
case '\0':
case ' ': case '\t': case '\n': case '\r': // TODO others?
if (inword) { inword = 0; counted++; }
break;
default: inword = 1;
} while(*it++);
return counted;
}
int main(int argc, const char *argv[])
{
printf("%d\n", words(""));
printf("%d\n", words("\t"));
printf("%d\n", words(" a castle "));
printf("%d\n", words("my world is a castle"));
}
See the following example, you can follow the approach : count the whitespace between words .
int words(const char *sentence)
{
int count=0,i,len;
char lastC;
len=strlen(sentence);
if(len > 0)
{
lastC = sentence[0];
}
for(i=0; i<=len; i++)
{
if((sentence[i]==' ' || sentence[i]=='\0') && lastC != ' ')
{
count++;
}
lastC = sentence[i];
}
return count;
}
To test :
int main()
{
char str[30] = "a posse ad esse";
printf("Words = %i\n", words(str));
}
Output :
Words = 4
#include <ctype.h> // isspace()
int
nwords(const char *s) {
if (!s) return -1;
int n = 0;
int inword = 0;
for ( ; *s; ++s) {
if (!isspace(*s)) {
if (inword == 0) { // begin word
inword = 1;
++n;
}
}
else if (inword) { // end word
inword = 0;
}
}
return n;
}
bool isWhiteSpace( char c )
{
if( c == ' ' || c == '\t' || c == '\n' )
return true;
return false;
}
int wordCount( char *string )
{
char *s = string;
bool inWord = false;
int i = 0;
while( *s )
{
if( isWhiteSpace(*s))
{
inWord = false;
while( isWhiteSpace(*s) )
s++;
}
else
{
if( !inWord )
{
inWord = true;
i++;
}
s++;
}
}
return i;
}
Here is one of the solutions. It counts words with multiple spaces or just space or space followed by the word.
#include <stdio.h>
int main()
{
char str[80];
int i, w = 0;
printf("Enter a string: ");
scanf("%[^\n]",str);
for (i = 0; str[i] != '\0'; i++)
{
if((str[i]!=' ' && str[i+1]==' ')||(str[i+1]=='\0' && str[i]!=' '))
{
w++;
}
}
printf("The number of words = %d", w );
return 0;
}
I know this is an old thread, but perhaps someone needs a simple solution, just checks for blank space in ascii and compares current char to that while also makign sure first char is not a space, cheers!
int count_words(string text){
int counter = 1;
int len = strlen(text);
for(int i = 0; i < len; i++){
if(text[i] == 32 && i != 0) {
counter++;
}
}
return counter;}
Here is another solution:
#include <string.h>
int words(const char *s)
{
const char *sep = " \t\n\r\v\f";
int word = 0;
size_t len;
s += strspn(s, sep);
while ((len = strcspn(s, sep)) > 0) {
++word;
s += len;
s += strspn(s, sep);
}
return word;
}
#include<stdio.h>
int main()
{
char str[50];
int i, count=1;
printf("Enter a string:\n");
gets(str);
for (i=0; str[i]!='\0'; i++)
{
if(str[i]==' ')
{
count++;
}
}
printf("%i\n",count);
}
#include<stdio.h>
#include<string.h>
int getN(char *);
int main(){
char str[999];
printf("Enter Sentence: "); gets(str);
printf("there are %d words", getN(str));
}
int getN(char *str){
int i = 0, len, count= 0;
len = strlen(str);
if(str[i] >= 'A' && str[i] <= 'z')
count ++;
for (i = 1; i<len; i++)
if((str[i]==' ' || str[i]=='\t' || str[i]=='\n')&& str[i+1] >= 'A' && str[i+1] <= 'z')
count++;
return count;
}
#include <stdio.h>
int wordcount (char *string){
int n = 0;
char *p = string ;
int flag = 0 ;
while(isspace(*p)) p++;
while(*p){
if(!isspace(*p)){
if(flag == 0){
flag = 1 ;
n++;
}
}
else flag = 0;
p++;
}
return n ;
}
int main(int argc, char **argv){
printf("%d\n" , wordcount(" hello world\nNo matter how many newline and spaces"));
return 1 ;
}
I found the posted question after finishing my function for a C class I'm taking. I saw some good ideas from code people have posted above. Here's what I had come up with for an answer. It certainly is not as concise as other's, but it does work. Maybe this will help someone in the future.
My function receives an array of chars in. I then set a pointer to the array to speed up the function if it was scaled up. Next I found the length of the string to loop over. I then use the length of the string as the max for the 'for' loop.
I then check the pointer which is looking at array[0] to see if it is a valid character or punctuation. If pointer is valid then increment to next array index. The word counter is incremented when the first two tests fail. The function then will increment over any number of spaces until the next valid char is found.
The function ends when null '\0' or a new line '\n' character is found. Function will increment count one last time right before it exit to account for the word preceding null or newline. Function returns count to the calling function.
#include <ctype.h>
char wordCount(char array[]) {
char *pointer; //Declare pointer type char
pointer = &array[0]; //Pointer to array
int count; //Holder for word count
count = 0; //Initialize to 0.
long len; //Holder for length of passed sentence
len = strlen(array); //Set len to length of string
for (int i = 0; i < len; i++){
//Is char punctuation?
if (ispunct(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Is the char a valid character?
if (isalpha(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Not a valid char. Increment counter.
count++;
//Look out for those empty spaces. Don't count previous
//word until hitting the end of the spaces.
if (*(pointer) == ' ') {
do {
pointer += 1;
} while (*(pointer) == ' ');
}
//Important, check for end of the string
//or newline characters.
if (*pointer == '\0' || *pointer == '\n') {
count++;
return(count);
}
}
//Redundent return statement.
count++;
return(count);
}
I had this as an assignment...so i know this works.
The function gives you the number of words, average word length, number of lines and number of characters.
To count words, you have to use isspace() to check for whitespaces. if isspace is 0 you know you're not reading whitespace. wordCounter is a just a way to keep track of consecutive letters. Once you get to a whitespace, you reset that counter and increment wordCount. My code below:
Use isspace(c) to
#include <stdio.h>
#include <ctype.h>
int main() {
int lineCount = 0;
double wordCount = 0;
double avgWordLength = 0;
int numLines = 0;
int wordCounter = 0;
double nonSpaceChars = 0;
int numChars = 0;
printf("Please enter text. Use an empty line to stop.\n");
while (1) {
int ic = getchar();
if (ic < 0) //EOF encountered
break;
char c = (char) ic;
if (isspace(c) == 0 ){
wordCounter++;
nonSpaceChars++;
}
if (isspace(c) && wordCounter > 0){
wordCount++;
wordCounter =0;
}
if (c == '\n' && lineCount == 0) //Empty line
{
break;
}
numChars ++;
if (c == '\n') {
numLines ++;
lineCount = 0;
}
else{
lineCount ++;
}
}
avgWordLength = nonSpaceChars/wordCount;
printf("%f\n", nonSpaceChars);
printf("Your text has %d characters and %d lines.\nYour text has %f words, with an average length of %3.2f ", numChars, numLines, wordCount, avgWordLength);
}
Here is one solution. This one will count words correctly even if there are multiple spaces between words, no spaces around interpuncion symbols, etc. For example: I am,My mother is. Elephants ,fly away.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int countWords(char*);
int main() {
char string[1000];
int wordsNum;
printf("Unesi nisku: ");
gets(string); /*dont use this function lightly*/
wordsNum = countWords(string);
printf("Broj reci: %d\n", wordsNum);
return EXIT_SUCCESS;
}
int countWords(char string[]) {
int inWord = 0,
n,
i,
nOfWords = 0;
n = strlen(string);
for (i = 0; i <= n; i++) {
if (isalnum(string[i]))
inWord = 1;
else
if (inWord) {
inWord = 0;
nOfWords++;
}
}
return nOfWords;
}
this is a simpler function to calculate the number of words
int counter_words(char* a){`
// go through chars in a
// if ' ' new word
int words=1;
int i;
for(i=0;i<strlen(a);++i)
{
if(a[i]==' ' && a[i+1] !=0)
{
++words;
}
}
return words;}
Each input line should consist of
- A type name, which must be one of the following: char, int, short, long, float, or double.
- One or more individual declaration specifications separated by commas.
- A semicolon marking the end of line.
The program should exit if it reads a blank input line.
I wrote the following code for this program. It seems to work well,except thefollowing warning I get :
d:\documents\documents\visual studio 2012\projects\project3\project3\source.c(108): warning C4715: 'theSizeOf' : not all control paths return a value.
By the way, I wonder if it can be improved (maby by using strtok?). I also would like to add a file in this program which is to contain the output and I am not sure at all how it has to be done.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void bytesPerValue(char str[]);
int theSizeOf(char *str);
int strToNumber(char *str);
void main()
{
char str[50];
gets(str);
bytesPerValue(str);
}
void bytesPerValue(char str[]) //Ex5
{
int i = 0, j = 0;
int temp = 1;
int size;
char* tempChar = (char*)malloc((strlen(str))*sizeof(tempChar));
while (!isspace(str[i]) || str[i]=='*') //checking the type of the variables
{
tempChar[j] = str[i];
i++;
j++;
}
tempChar[j] = '\0';
size = theSizeOf(tempChar);
j = 0;
i++;
while (str[i] != ';')
{
if (isalpha(str[i]) || str[i]=='_') // for normal variables and arrays
{
while (str[i] != ',' && str[i] != ';') //runs until ', ' or '; '
{
if (isspace(str[i]))
{
while (isspace(str[i]))
i++;
}
if (str[i] == '[') //checks if it is array
{
printf("%c", str[i]);
i++;
while (str[i] != ']')
{
tempChar[j] = str[i]; //copies the value in the string
i++;
j++;
}
tempChar[j] = '\0';
temp = strToNumber(tempChar); //converting to number so I can valuate the bytes
}
printf("%c", str[i]);
i++;
if (isspace(str[i]))
{
while (isspace(str[i]))
i++;
}
}
printf(" requires %d bytes \n", temp*size);
}
if (str[i] == '*') //for pointers
{
while (str[i] != ',' && str[i] != ';')
{
printf("%c", str[i]);
i++;
if (isspace(str[i]))
{
while (isspace(str[i]))
i++;
}
}
printf(" requires %d bytes \n", 4);
}
if (str[i] != ';')
i++;
}
}
int theSizeOf(char* str) // checking the size of the variable
{
if (strcmp(str, "int")==0 || strcmp(str, "long")==0 || strcmp(str, "float")==0)
return 4;
if (strcmp(str, "char")==0)
return 1;
if (strcmp(str, "double")==0)
return 8;
if (strcmp(str, "short")==0)
return 2;
}
int strToNumber(char* str) //converting the string to number
{
int temp=1;
int num=0;
int t;
int i;
int length = strlen(str);
for (i = length-1; i >= 0; i--)
{
t = str[i] - '0';
num += t * temp;
temp *= 10;
}
return num;
}
As Sourav Ghosh mentioned this is definetly post for Code Review.
But since you already wasted your time posting here, I would advise you read up this:
Please explain the output of sizeof()
I am not quite sure why you defined your own function when you could have used the sizeof operator which do exactly what your function is doing.
Edit:
Another good example
Edint 2.0 : The warning you got is the compiler basicly saying, "What will happen if neither of your cases are matched?" . In more simple words it asks for a else case in which to go in the scenario where none of the if's match the case.
Regarding how to write the value to a file, you can use fprintf();
FILE *f = fopen("file.txt", "w");
if (f == NULL)
{
printf("Error opening file!\n");
exit(1);
}
int i = 1;
fprintf(f,"%d", i);
fclose(f);
More information and examples for fprintf
I have changed my code by using sizeof and I get a wrong output.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void bytesPerValue(char str[]);
int strToNumber(char *str);
void main()
{
char str[50];
gets(str);
bytesPerValue(str);
}
void bytesPerValue(char str[])
{
int i = 0, j = 0;
int temp = 1;
int size;
char* tempChar = (char*)malloc((strlen(str))*sizeof(tempChar));
while (str[i]!=' ' || str[i]=='*') //checking the type of the variables//
{
tempChar[j] = str[i];
i++;
j++;
}
tempChar[j] = '\0';
size = sizeof(tempChar);
j = 0;
i++;
while (str[i] != ';')
{
if (isalpha(str[i]) || str[i]=='_') // for variables and arrays//
{
while (str[i] != ',' && str[i] != ';') //runs until ', ' or '; ' //
{
if (str[i]==' ')
{
while (str[i]==' ')
i++;
}
if (str[i] == '[') //checks if it is array//
{
printf("%c", str[i]);
i++;
while (str[i] != ']')
{
tempChar[j] = str[i]; //copies the value in the string//
i++;
j++;
}
tempChar[j] = '\0';
temp = strToNumber(tempChar); //converting to number in order to valuate the bytes//
}
printf("%c", str[i]);
i++;
if (isspace(str[i]))
{
while (isspace(str[i]))
i++;
}
}
printf(" requires %d bytes \n", temp*size);
}
if (str[i] == '*') //for pointers//
{
while (str[i] != ',' && str[i] != ';')
{
printf("%c", str[i]);
i++;
if (str[i]==' ')
{
while (str[i]==' ')
i++;
}
}
printf(" requires %d bytes \n", 4);
}
if (str[i] != ';')
i++;
}
}
For example, for the following input: char c, *cprt, carray[80];
I get the following output:
c requires 4 bytes
*cprt requires 4 bytes
caaray[] requires 320 bytes
which is wrong...
I have just edited my code, not using sizeof. I also add a use of file in my code. I think it works well now. I would be happy if you may please tell me what you think about it, whether my code should be improved or fixed.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
void bytesPerValue(char str[], char* filename) ;
int theSizeOf(char *str);
int strToNumber(char *str);
void main()
{
char str[50];
gets(str);
bytesPerValue(str,"input.txt");
}
void bytesPerValue(char str[], char* filename)
{
int i = 0, j = 0;
int temp = 1;
int size;
char* tempChar = (char*)malloc((strlen(str))*sizeof(tempChar));
FILE *f=fopen(filename,"w");
if (f==NULL)
exit(1);
while (str[i]!=' ' || str[i]=='*') //checking the type of the variables//
{
tempChar[j] = str[i];
i++;
j++;
}
tempChar[j] = '\0';
size = theSizeOf(tempChar);
j = 0;
i++;
while (str[i] != ';')
{
if (isalpha(str[i]) || str[i]=='_') // for variables and arrays//
{
while (str[i] != ',' && str[i] != ';') //runs until ', ' or '; ' //
{
if (str[i]==' ')
{
while (str[i]==' ')
i++;
}
if (str[i] == '[') //checks if it is array//
{
printf("%c", str[i]);
i++;
while (str[i] != ']')
{
tempChar[j] = str[i]; //copies the value in the string//
i++;
j++;
}
tempChar[j] = '\0';
temp = strToNumber(tempChar); //converting to number in order to valuate the bytes//
}
printf("%c", str[i]);
i++;
if (isspace(str[i]))
{
while (isspace(str[i]))
i++;
}
}
fprintf(f," requires %d bytes \n", temp*(sizeof(temp)));
}
if (str[i] == '*') //for pointers//
{
while (str[i] != ',' && str[i] != ';')
{
printf("%c", str[i]);
i++;
if (str[i]==' ')
{
while (str[i]==' ')
i++;
}
}
fprintf(f," requires %d bytes \n", 4);
}
if (str[i] != ';')
i++;
}
fclose(f);
}
int theSizeOf(char* str) // checking the size of the variable
{
if (strcmp(str, "int")==0 || strcmp(str, "long")==0 || strcmp(str, "float")==0)
return 4;
else if (strcmp(str, "char")==0)
return 1;
else if (strcmp(str, "double")==0)
return 8;
else if (strcmp(str, "short")==0)
return 2;
else
return 0;
}
int strToNumber(char* str) //converting the string to number//
{
int temp=1;
int num=0;
int t;
int i;
int length = strlen(str);
for (i = length-1; i >= 0; i--)
{
t = str[i] - '0';
num += t * temp;
temp *= 10;
}
return num;
}
thank you all for your help!
example of using sscanf.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFF_SIZE 128
void bytesPerValue(FILE *ofp, char str[]);
int main(int argc, char *argv[]){
char str[BUFF_SIZE];
char *inp_filename, *out_filename;
FILE *ifp, *ofp;
if(argc != 3){
fprintf(stderr, "Usage: %s input_filename output_filename\n", argv[0]);
return EXIT_FAILURE;
}
inp_filename = argv[1], out_filename = argv[2];
if(NULL==(ifp = fopen(inp_filename, "r"))){
fprintf(stderr, "Couldn't open file : %s\n", inp_filename);
return EXIT_FAILURE;
}
if(NULL==(ofp = fopen(out_filename, "w"))){
fprintf(stderr, "Couldn't open file : %s\n", out_filename);
return EXIT_FAILURE;
}
while(fgets(str, sizeof str, ifp)){
//str[strcspn(str, "\n")] = 0;//chomp newline
bytesPerValue(ofp, str);
}
fclose(ifp), fclose(ofp);
}
struct size_of_type {
const char *name;
int size;
} Type_size[] = {
{ "char" , sizeof(char) },
{ "double", sizeof(double) },
{ "float" , sizeof(float) },
{ "int" , sizeof(int) },
{ "long" , sizeof(long) },
{ "short" , sizeof(short) },
};
int cmp(const void *a, const void *b){
return strcmp(*(char **)a, *(char **)b);
}
int theSizeOf(const char *type){
struct size_of_type *stp;
if(!*type)//""
return 0;
stp = bsearch(&type, Type_size, sizeof(Type_size)/sizeof(*Type_size), sizeof(*Type_size), cmp);
return stp ? stp->size : -1;
}
enum { UNKNOWN = -1, NONE };
#define UNDER_BAR "_"
#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
#define ID_CHARS UPPERCASE LOWERCASE UNDER_BAR
void bytesPerValue(FILE *fp, char str[]) {
char type[16] = "", rest[BUFF_SIZE];
char field[BUFF_SIZE], id[BUFF_SIZE], dummy[BUFF_SIZE];
char *sp, sep=0, end_b, dispname[BUFF_SIZE];
int typeSize, size, subscript, len;
sscanf(str, "%s %[^\n]", type, rest);
typeSize = theSizeOf(type);
if(typeSize == UNKNOWN){
fprintf(fp, "%s is unknown type in '%s'\n", type, str);
return;
} else if(typeSize == NONE){//blank line
return;
}
sp = rest;
for(sp = rest; 2 == sscanf(sp, " %[^,;]%c%n", field, &sep, &len) && (sep == ',' || sep == ';'); sp += len){
if(3 == sscanf(field, " * %[" ID_CHARS "] [%d %c %s", id, &subscript, &end_b, dummy) && subscript > 0 && end_b == ']'){//array of pointer
typeSize = sizeof(void *);
size = typeSize * subscript;
sprintf(dispname, "*%s[]", id);
}
else if(3 == sscanf(field, " %[" ID_CHARS "] [%d %c %s", id, &subscript, &end_b, dummy) && subscript > 0 && end_b == ']'){//array
size = typeSize * subscript;
sprintf(dispname, "%s[]", id);
}
else if(1 == sscanf(field, " * %[" ID_CHARS "] %s", id, dummy)){//pointer
size = typeSize = sizeof(void *);
sprintf(dispname, "*%s", id);
}
else if(1 == sscanf(field, " %[" ID_CHARS "] %s", id, dummy)){//normal variable
size = typeSize;
strcpy(dispname, id);
} else {
fprintf(fp, "'%s' is invalid format.\n", field);
continue;
}
fprintf(fp, "%s requires %d bytes \n", dispname, size);
}
if(sep != ';'){
fprintf(fp, "'%s' is invalid format.\n", str);
}
}
I need to build a program that receives up to 30 chars from the user, and then to play with it.
For example, I need to reverses the sentence and then print it, or to rotate it.
I have been trying to copy the words of the sentence one by one to a matrix of [30][31], but it does not working... any ideas?
I cannot use pointers...
thanks for the help :)
#include <stdio.h>
#include <string.h>
void main(){
int i=0,
j=0,
wrongData=0,
charCounter=0,
word=0,
letter=0;
char st[100],
arr[100]={0},
mat[30][31]={0};
printf("Please, enter your sentence >");
gets(st);
while(i<strlen(st)){
if('A'<=st[i] && st[i]<='Z'){
charCounter++;
arr[j] = st[i];
i++;
j++;
} else if(st[i]==' '){
arr[j] = ' ';
i++;
j++;
while(st[i] == ' '){
i++;
}
} else if(st[i]=='\0'){
arr[j] = '\0';
break;
} else {
puts("ERROR: Incorrect data, try again.");
wrongData=1;
break;
}
if(wrongData==0){
if(charCounter>30){
puts("ERROR: Incorrect data, try again.");
}
}
}
puts(st);
puts(arr);
if(arr[j]==' '){
word++;
}
while(arr[j]!=' ' && letter<32){
strcpy(mat[word],arr);
}
if(arr[j]=='\0'){
mat[word][letter]=arr[j];
}
puts(mat[word]);
}
Taking into account your comment
the problem is that i need to reverse the words not the letters... for
example: if the string is cats hates dogs, i need to get at the end
dogs hates cats
then I think you mean something as the following
#include <stdio.h>
#include <ctype.h>
#include <string.h>
char * reverse_words( char s[] )
{
for ( char *p = s, *q = s; *p; p = q )
{
while ( isspace( ( unsigned char )*p ) ) ++p;
q = p;
while ( *q && !isspace( ( unsigned char )*q ) ) ++q;
for ( size_t i = 0; i < ( q - p ) / 2; i++ )
{
char c = p[i];
p[i] = q[-i-1];
q[-i-1] = c;
}
}
for ( size_t i = 0, n = strlen( s ); i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n-i-1];
s[n-i-1] = c;
}
return s;
}
int main( void )
{
char s[] = "cats hates dogs";
puts( s );
puts( reverse_words( s ) );
return 0;
}
The program output is
cats hates dogs
dogs hates cats
Here is another approach. The idea is to go through the string and record the index where each word starts and ends. Then the words can be printed in reverse order afterwards. (btw - it will also be easy to rotate the words).
#include<stdio.h>
#include <string.h>
int main() {
char st[100] = "here we go again";
int start[30] = { 0 };
int end[30] = { 0 };
int count = 0;
int len = strlen(st);
int i, j;
// Find start and end index of each word
start[0] = 0;
for(i = 0; i < len; ++i)
{
if (st[i] == ' ')
{
end[count] = i;
++count;
start[count] = i + 1;
}
}
end[count] = len;
// Print the words in reverse order
for(i=count; i >= 0; --i)
{
for (j = start[i]; j < end[i]; ++j)
{
printf("%c", st[j]);
}
printf(" ");
}
printf("\n");
return 0;
}
output:
again go we here
fix your approach like this:
#include <stdio.h>
//#include <string.h>
#define MAX_LEN 30
int main(void){
int i, j, n, word;
char st[100], arr[100], mat[MAX_LEN / 2][MAX_LEN + 1];
printf("Please, enter your sentence (up to %d chars and A-Z or space)\n>", MAX_LEN);fflush(stdout);
scanf("%99[^\n]%*c", st);
//validate and reduce of spaces
for(j = i = 0; st[i]; ++i){
if(i > MAX_LEN){
fputs("ERROR: Incorrect data, try again.\n", stderr);
return 1;
}
if('A'<=st[i] && st[i]<='Z'){
arr[j++] = st[i];
} else if(st[i]==' '){
arr[j++] = ' ';
while(st[++i] == ' ')//Skip a continuous space
;
--i;//one back for next loop
} else {
fputs("ERROR: Incorrect data, try again.\n", stderr);
return 1;
}
}
arr[j] = '\0';//st[i]=='\0' never become true in loop
#if DEBUG
puts(st);
puts(arr);
#endif
//split to word
for(word = j = i = 0; arr[i];){
while(arr[i] == ' ')
++i;//skip space
while(arr[i] != ' ' && arr[i] != '\0')
mat[word][j++] = arr[i++];
mat[word++][j] = '\0';
j = 0;
}
#if DEBUG
for(i = 0; i < word; ++i)
puts(mat[i]);
#endif
puts("reverse word");
for(i = 0; i < word; ++i){
if(i)
putchar(' ');
printf("%s", mat[word-1-i]);
}
puts("\nrotate word");
printf("Please, enter number of rotate\n>");fflush(stdout);
scanf("%d", &n);
for(i = 0; i < word; ++i){
if(i)
putchar(' ');
printf("%s", mat[(i+n)%word]);//rotate left
}
}
I'm making a program to delete extra spaces in c and count how many extra space it deletes. The program counts the extra spaces but it doesn't print the string that doesn't have extra spaces. I'll show you my code:
#include <stdio.h>
#include <stdlib.h>
/*
*
*/
char delete_spaces(char oracion[100])
{
int i;
for (i=0;oracion[i]!='\0';i++){
if (oracion[i]==' '&&oracion[i+1]==' '){
oracion[i]=oracion[i+1];
}
}
return(oracion[100]);
}
int count_spaces(char oracion[100])
{
int i,number_spaces=0;
for (i=0;oracion[i]!='\0';i++){
if (oracion[i]==' '&&oracion[i+1]==' '){
number_spaces+=1;
}
}
return(number_spaces);
}
int main(void){
char frase[100],frase2[100];
int num_spaces;
printf("Write here the phrase:");
gets(frase);
frase2[100]=delete_spaces(frase);
num_spaces=count_spaces(frase);
printf("%s",frase2);
printf("%d",num_spaces);
return 0;
}
Could be this what you need?:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int delete_spaces(char *s1,char *s2){
int found = 0;
int i = 0, j = 0;
while(s1[i] != '\0'){
if (((s1[i] == ' ') && (s1[i+1] == ' ')) || ((s1[i] == '\t') && (s1[i+1] == '\t'))){
found++;
} else {
s2[j++] = s1[i];
}
i++;
}
s2[j] = '\0';
printf("s2 = %s\n",s2);
return found;
}
int main(void){
char frase[100], frase2[100];
int num_spaces;
printf("Write here the phrase:");
if((fgets(frase,99,stdin)) == NULL){
printf("Error\n");
}
num_spaces=delete_spaces(frase,frase2);
printf("Number of deleted spaces = %d\n",num_spaces);
return 0;
}
Output:
I'm going to sleep now Goodbye
s2 = I'm going to sleep now Goodbye
Number of deleted spaces = 13
In addition to Barmar's suggestion above, you probably want frase2 to actually be a char* type, and you want to assign it not to the index 100, but the pointer itself:
int main(void) {
char frase[100];
char *frase2;
...
frase2 = delete_spaces(frase);
...
}
You can't assign to an array the way you're trying to do it. You should pass frase2 as a second argument to the function. Then it can copy from one array to the other, skipping over duplicate spaces.
int delete_spaces(char oracion[100], char oracion2[100])
{
int deletions = 0;
int i;
int dest = 0;
for (i=0; oracion[i]!='\0'; i++){
if (oracion[i]==' '&&oracion[i+1]==' '){
deletions++;
} else {
oracion2[dest++] = oracion[i];
}
}
oracion2[dest] = '\0'; // don't forget to terminate the string
return deletions;
}
Notice that this does the counting as it's deleting, so you don't need a separate function for this.
Then you would call it from main as:
num_spaces = delete_spaces(frase, frase2);
#include <stdio.h>
#include <stdlib.h>
typedef struct sentence {//wrap by struct
char oracion[100];
} sentence;
sentence delete_spaces(sentence frase)//make copy
{
int i, j;
for (j=i=0; frase.oracion[i] != '\0'; i++){
if(j && frase.oracion[j-1] == ' ' && frase.oracion[i] == ' '){
continue;
}
frase.oracion[j++] = frase.oracion[i];
}
frase.oracion[j] = '\0';
return frase;
}
int count_spaces(sentence frase)
{
int i, j, number_spaces = 0;
for (j=i=0; frase.oracion[i] != '\0'; i++){
if(j && frase.oracion[j-1] == ' ' && frase.oracion[i] == ' '){
number_spaces += 1;
continue;
}
frase.oracion[j++] = frase.oracion[i];
}
return number_spaces;
}
int main(void){
sentence frase, frase2;
int num_spaces;
printf("Write here the phrase:");
scanf("%99[^\n]%*c", frase.oracion);
frase2 = delete_spaces(frase);//make copy to frase2
num_spaces = count_spaces(frase);
printf("%s\n", frase2.oracion);
printf("%d\n", num_spaces);
return 0;
}
I need to write a function that will count words in a string. For the
purpose of this assignment, a "word" is defined to be a sequence
of non-null, non-whitespace characters, separated from other words by
whitespace.
This is what I have so far:
int words(const char sentence[ ]);
int i, length=0, count=0, last=0;
length= strlen(sentence);
for (i=0, i<length, i++)
if (sentence[i] != ' ')
if (last=0)
count++;
else
last=1;
else
last=0;
return count;
I am not sure if it works or not because I can't test it until my whole program is finished and I am not sure it will work, is there a better way of writing this function?
You needed
int words(const char sentence[])
{
}
(note braces).
For loops go with ; instead of ,.
Without any disclaimer, here's what I'd have written:
See it live http://ideone.com/uNgPL
#include <string.h>
#include <stdio.h>
int words(const char sentence[ ])
{
int counted = 0; // result
// state:
const char* it = sentence;
int inword = 0;
do switch(*it) {
case '\0':
case ' ': case '\t': case '\n': case '\r': // TODO others?
if (inword) { inword = 0; counted++; }
break;
default: inword = 1;
} while(*it++);
return counted;
}
int main(int argc, const char *argv[])
{
printf("%d\n", words(""));
printf("%d\n", words("\t"));
printf("%d\n", words(" a castle "));
printf("%d\n", words("my world is a castle"));
}
See the following example, you can follow the approach : count the whitespace between words .
int words(const char *sentence)
{
int count=0,i,len;
char lastC;
len=strlen(sentence);
if(len > 0)
{
lastC = sentence[0];
}
for(i=0; i<=len; i++)
{
if((sentence[i]==' ' || sentence[i]=='\0') && lastC != ' ')
{
count++;
}
lastC = sentence[i];
}
return count;
}
To test :
int main()
{
char str[30] = "a posse ad esse";
printf("Words = %i\n", words(str));
}
Output :
Words = 4
#include <ctype.h> // isspace()
int
nwords(const char *s) {
if (!s) return -1;
int n = 0;
int inword = 0;
for ( ; *s; ++s) {
if (!isspace(*s)) {
if (inword == 0) { // begin word
inword = 1;
++n;
}
}
else if (inword) { // end word
inword = 0;
}
}
return n;
}
bool isWhiteSpace( char c )
{
if( c == ' ' || c == '\t' || c == '\n' )
return true;
return false;
}
int wordCount( char *string )
{
char *s = string;
bool inWord = false;
int i = 0;
while( *s )
{
if( isWhiteSpace(*s))
{
inWord = false;
while( isWhiteSpace(*s) )
s++;
}
else
{
if( !inWord )
{
inWord = true;
i++;
}
s++;
}
}
return i;
}
Here is one of the solutions. It counts words with multiple spaces or just space or space followed by the word.
#include <stdio.h>
int main()
{
char str[80];
int i, w = 0;
printf("Enter a string: ");
scanf("%[^\n]",str);
for (i = 0; str[i] != '\0'; i++)
{
if((str[i]!=' ' && str[i+1]==' ')||(str[i+1]=='\0' && str[i]!=' '))
{
w++;
}
}
printf("The number of words = %d", w );
return 0;
}
I know this is an old thread, but perhaps someone needs a simple solution, just checks for blank space in ascii and compares current char to that while also makign sure first char is not a space, cheers!
int count_words(string text){
int counter = 1;
int len = strlen(text);
for(int i = 0; i < len; i++){
if(text[i] == 32 && i != 0) {
counter++;
}
}
return counter;}
Here is another solution:
#include <string.h>
int words(const char *s)
{
const char *sep = " \t\n\r\v\f";
int word = 0;
size_t len;
s += strspn(s, sep);
while ((len = strcspn(s, sep)) > 0) {
++word;
s += len;
s += strspn(s, sep);
}
return word;
}
#include<stdio.h>
int main()
{
char str[50];
int i, count=1;
printf("Enter a string:\n");
gets(str);
for (i=0; str[i]!='\0'; i++)
{
if(str[i]==' ')
{
count++;
}
}
printf("%i\n",count);
}
#include<stdio.h>
#include<string.h>
int getN(char *);
int main(){
char str[999];
printf("Enter Sentence: "); gets(str);
printf("there are %d words", getN(str));
}
int getN(char *str){
int i = 0, len, count= 0;
len = strlen(str);
if(str[i] >= 'A' && str[i] <= 'z')
count ++;
for (i = 1; i<len; i++)
if((str[i]==' ' || str[i]=='\t' || str[i]=='\n')&& str[i+1] >= 'A' && str[i+1] <= 'z')
count++;
return count;
}
#include <stdio.h>
int wordcount (char *string){
int n = 0;
char *p = string ;
int flag = 0 ;
while(isspace(*p)) p++;
while(*p){
if(!isspace(*p)){
if(flag == 0){
flag = 1 ;
n++;
}
}
else flag = 0;
p++;
}
return n ;
}
int main(int argc, char **argv){
printf("%d\n" , wordcount(" hello world\nNo matter how many newline and spaces"));
return 1 ;
}
I found the posted question after finishing my function for a C class I'm taking. I saw some good ideas from code people have posted above. Here's what I had come up with for an answer. It certainly is not as concise as other's, but it does work. Maybe this will help someone in the future.
My function receives an array of chars in. I then set a pointer to the array to speed up the function if it was scaled up. Next I found the length of the string to loop over. I then use the length of the string as the max for the 'for' loop.
I then check the pointer which is looking at array[0] to see if it is a valid character or punctuation. If pointer is valid then increment to next array index. The word counter is incremented when the first two tests fail. The function then will increment over any number of spaces until the next valid char is found.
The function ends when null '\0' or a new line '\n' character is found. Function will increment count one last time right before it exit to account for the word preceding null or newline. Function returns count to the calling function.
#include <ctype.h>
char wordCount(char array[]) {
char *pointer; //Declare pointer type char
pointer = &array[0]; //Pointer to array
int count; //Holder for word count
count = 0; //Initialize to 0.
long len; //Holder for length of passed sentence
len = strlen(array); //Set len to length of string
for (int i = 0; i < len; i++){
//Is char punctuation?
if (ispunct(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Is the char a valid character?
if (isalpha(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Not a valid char. Increment counter.
count++;
//Look out for those empty spaces. Don't count previous
//word until hitting the end of the spaces.
if (*(pointer) == ' ') {
do {
pointer += 1;
} while (*(pointer) == ' ');
}
//Important, check for end of the string
//or newline characters.
if (*pointer == '\0' || *pointer == '\n') {
count++;
return(count);
}
}
//Redundent return statement.
count++;
return(count);
}
I had this as an assignment...so i know this works.
The function gives you the number of words, average word length, number of lines and number of characters.
To count words, you have to use isspace() to check for whitespaces. if isspace is 0 you know you're not reading whitespace. wordCounter is a just a way to keep track of consecutive letters. Once you get to a whitespace, you reset that counter and increment wordCount. My code below:
Use isspace(c) to
#include <stdio.h>
#include <ctype.h>
int main() {
int lineCount = 0;
double wordCount = 0;
double avgWordLength = 0;
int numLines = 0;
int wordCounter = 0;
double nonSpaceChars = 0;
int numChars = 0;
printf("Please enter text. Use an empty line to stop.\n");
while (1) {
int ic = getchar();
if (ic < 0) //EOF encountered
break;
char c = (char) ic;
if (isspace(c) == 0 ){
wordCounter++;
nonSpaceChars++;
}
if (isspace(c) && wordCounter > 0){
wordCount++;
wordCounter =0;
}
if (c == '\n' && lineCount == 0) //Empty line
{
break;
}
numChars ++;
if (c == '\n') {
numLines ++;
lineCount = 0;
}
else{
lineCount ++;
}
}
avgWordLength = nonSpaceChars/wordCount;
printf("%f\n", nonSpaceChars);
printf("Your text has %d characters and %d lines.\nYour text has %f words, with an average length of %3.2f ", numChars, numLines, wordCount, avgWordLength);
}
Here is one solution. This one will count words correctly even if there are multiple spaces between words, no spaces around interpuncion symbols, etc. For example: I am,My mother is. Elephants ,fly away.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int countWords(char*);
int main() {
char string[1000];
int wordsNum;
printf("Unesi nisku: ");
gets(string); /*dont use this function lightly*/
wordsNum = countWords(string);
printf("Broj reci: %d\n", wordsNum);
return EXIT_SUCCESS;
}
int countWords(char string[]) {
int inWord = 0,
n,
i,
nOfWords = 0;
n = strlen(string);
for (i = 0; i <= n; i++) {
if (isalnum(string[i]))
inWord = 1;
else
if (inWord) {
inWord = 0;
nOfWords++;
}
}
return nOfWords;
}
this is a simpler function to calculate the number of words
int counter_words(char* a){`
// go through chars in a
// if ' ' new word
int words=1;
int i;
for(i=0;i<strlen(a);++i)
{
if(a[i]==' ' && a[i+1] !=0)
{
++words;
}
}
return words;}