Count all characters in string but spaces [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How can I count sum of characters in string excluding blank spaces?! I wrote a code but it counts blank spaces too. Any suggestions? here is what I have:
void main()
{
char str[100];
int len, space;
printf( "Enter string:\n ");
printf("\n");
gets(str);
len = strlen(str);
printf("\n");
printf("\n No.of characters in string is %d " , len );
getch();
}

For simple spaces try this
len = strlen(str);
int nchar = 0
for(int i = 0; i != len; i++) {
if(str[i] != ' ') {
nchar++;
}
}
printf("nchar = %d\n", nchar);
For all whitespace ( space, tab, newline ) try this:
#include <ctype.h> // this line must be in the top of the file
len = strlen(str);
int nchar = 0;
for(int i = 0; i != len; i++) {
if(!isspace(str[i])) {
nchar++;
}
}
printf("nchar = %d\n", nchar);
Other ways you might see in code are:
int nchar = 0;
for(char *p = str; *p; nchar += (*p++ != ' '));
and
int nchar = 0;
for(char *p = str; *p; nchar += isspace(*p++) == 0);
But those are less obvious.

You need to iterate over string and check all characters, counting only non-space chars. Something like:
int i;
int len = strlen(str);
int count = 0;
for (i = 0; i < len; i++) {
char c = str[i];
if ( /* check that char is not space */ )
count++;
}
Alternatively, you can count all space characters and then calculate len - nspaces.

Related

How to print length of each word in a string before the each Word

I want to print the length of each word in a string.
I have tried but not getting right answer. After running the code it will print the length of each word after the word instead of printing before the each word.
char str[20] = "I Love India";
int i, n, count = 0;
n = strlen(str);
for (i = 0; i <= n; i++) {
if (str[i] == ' ' || str[i] == '\0') {
printf("%d", count);
count = 0;
} else {
printf("%c", str[i]);
count++;
}
}
I except the output is 1I 4Love 5India, but the actual output is I1 Love4 India5.
You can use strtok as Some programmer dude sugested. You may want to make a copy of the original string as strtok modifies the passed string. Also strtok is not thread-safe and must be replaced with strtok_r when working with multi-threaded programs.
#include <stdio.h>
#include <stdlib.h>
/* for strtok */
#include <string.h>
int main() {
char str[20] = "I Love India";
int n;
char* tok = strtok(str, " ");
while (tok != NULL) {
n = strlen(tok);
printf("%d%s ", n, tok);
tok = strtok(NULL, " ");
}
return EXIT_SUCCESS;
}
You want to compute and print the length of each word before you print the word.
Here is a simple solution using strcspn(), a standard function that should be used more often:
#include <stdio.h>
#include <string.h>
int main() {
char str[20] = "I Love India";
char *p;
int n;
for (p = str; *p;) {
if (*p == ' ') {
putchar(*p++);
} else {
n = strcspn(p, " "); // compute the length of the word
printf("%d%.*s", n, n, p);
p += n;
}
}
printf("\n");
return 0;
}
Your approach is wrong as you print the word before the length. So you need to calculate the length first then print it and then print the word.
It could be something like:
int main(void)
{
char str[20]="I Love India";
size_t i = 0;
while(str[i])
{
if (str[i] == ' ') // consider using the isspace function instead
{
// Print the space
printf(" ");
++i;
}
else
{
size_t j = i;
size_t count = 0;
// Calculate word len
while(str[j] && str[j] != ' ')
{
++count;
++j;
}
// Print word len
printf("%zu", count);
// Print word
while(i<j)
{
printf("%c", str[i]);
++i;
}
}
}
}
The basic idea is to have two index variables for the string, i and j. The index i is at the words first character and index j is used for finding the end of the word. Once the end of word has been found, the length and the word can be printed.
This is what you want:
#include <stdio.h>
#include <string.h>
int main()
{
char str[20]="I Love India";
char buf[20];
int i,n,count=0;
n=strlen(str);
for (i=0; i <= n; i++) {
if(str[i]==' ' || str[i]=='\0'){
buf[count] = '\0';
printf("%d", count); /* Print the size of the last word */
printf("%s", buf); /* Print the buffer */
memset(buf, 0, sizeof(buf)); /* Clear the buffer */
count = 0;
} else {
buf[count] = str[i];
count++;
}
}
return 0;
}
You will want to keep a buffer of the word that is currently being counted. (buf)
Increment count each time its not a space or 0/. Then, when it is a space or a 0/, print count first, then buf. Then, we will clear buf and set count to 0, so that the variable i is still incrementing through the entire string str, but we are inserting the words into buf starting from 0.

String split in c without changing original [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
we have an school asignment to make a specific function of string split
the header and arguments of function is given cannot change them .
this function should split original by delimiter into array of string that store each part of string delimiter not included and in additon for each delimiter increase size
void stringSplit(const char *original, char result[50][256], int* size, char delim){
size_t begin = 0;
if(!original){
return;
}
for(size_t i=0; i<strlen(original);i++ ){
if (original[i] == delim){
int str_begin = 0;
for( ; begin < i; begin++ ){
result[*size][str_begin] = original[begin];
str_begin++;
}
(*size)++;
begin ++ ;
}
}
}
The idea is OK, but you have a couple of errors:
Your string copies are not '\0'-terminated. Also you are not taking into
account when multiple delimiters follow in a row.
If you are not allowed to use
functions like strchr and strncpy, then you can do this:
size_t str_begin = 0;
*size = 0; // the user may have passed an uninitialized int variable
for(size_t i = 0; original[i] && *size < 50; ++i)
{
if(original[i] == delim)
{
size_t sublen = i - str_begin;
if(sublen == 0)
{
// skip delimiter, last character was also a
// delimiter and/or the first character in
// original is a delimiter
str_begin++;
continue;
// or if you want to have empty words instead of skipping
// results[*size] = 0;
// (*size)++;
}
if(sublen > 256)
sublen = 256;
for(size_t j = 0; j < sublen; ++j)
result[*size][j] = original + str_begin + j;
result[*size][j] = 0; // \0-terminating string
(*size)++;
str_begin = i + 1; // updating str_begin to next char
}
}
The straight forward way of doing so is - as suggested by Barmar - to make a copy of the original string and then work with strtok() and strcpy.
Alternatively, you could use strchr in a loop to find the delimiters and memcpy to copy the memory between the previous delimiter and the next one. See the following code, which also takes the boundaries of the result array into account:
void stringSplit(const char *original, char result[50][256], int *size, char
delim)
{
if(!original){
return ;
}
*size = 0;
const char* nextDelim;
const char* prevDelim = original;
do {
nextDelim = strchr(prevDelim,delim);
size_t len = nextDelim ? (nextDelim - prevDelim) : strlen(prevDelim);
if (len >= 256) {
len = 256-1;
}
memcpy(result[*size],prevDelim,len);
result[*size][len] = '\0';
(*size)++;
prevDelim = nextDelim ? nextDelim+1 : NULL;
}
while(nextDelim && *size < 50);
}
int main() {
char result[50][256];
int size;
stringSplit("Hello, this, is", result, &size, ',');
return 0;
}
Hope it helps.

Kochan InsertString segmentation fault

I am working through Kochan's programming in C book and I am working on an exercise which requires a function to insert one character string inside another string, with the function call including where the string is to be inserted.
I have written the below code but I receive a segmentation fault whenever I enter the inputs. I think it's because the 'input' string is defined to the length of the user's input and then the insertString function tries to add additional characters to this string. I just can't see a way of defining the string as large enough to be able to take in additional characters. Do you think that this is the reason I am receiving a segmentation fault? Are there any other ways to go about this problem?
#include<stdio.h>
#include <string.h>
insertString(char input[], const char insert[], int position)
{
int i, j;
char temp[81];
j = strlen(input);
for(i = 0; i < position - 1; i++)
{
temp[i] = input[i];
}
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
for(j = i - j; input != '\0'; i++, j++)
{
temp[i] = input[j];
}
for(i = 0; temp[i] != '\0'; i++)
{
input[i] = temp[i];
}
input[i] = '\0';
}
void readLine(char buffer[])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
int main(void)
{
char input[81];
char insert[81];
int position;
printf("Enter the first string: ");
readLine(input);
printf("Enter the insert string: ");
readLine(insert);
printf("Enter placement position int: ");
scanf("%i", &position);
insertString(input, insert, position);
printf("The adjusted string is %s\n", input);
return 0;
}
There might be other reasons as well, but the following fragment will crash for sure:
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
The reason is that - since insert will not be increased or manipulated - this is an endless loop writing "indefinitely" long into temp. Once exceeding its length 80 (or a bit later) it will crash. I suppose you meant for(j = 0; insert[j] != '\0'; i++, j++), right?
Check all for loop conditions in insertString function. For example:
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
is infinite loop. Because of it you access memory out of temp array bounds. It causes UB and segmentation fault. Looks like you need insert[j] != '\0' condition here.
I'm familiar with this book. The author, Stephen Kochan, has a website with answers to the odd-numbered end of chapter exercises.
The website is at classroomm.com but you'll need to look around some to find the information.
Here is the info from that site related to this exercise:
Programming in C, exercise 10-7 (3rd edition) and 9-7 (4th edition)
/* insert string s into string source starting at i
This function uses the stringLength function defined
in the chapter.
Note: this function assumes source is big enough
to store the inserted string (dangerous!) */
void insertString (char source[], char s[], int i)
{
int j, lenS, lenSource;
/* first, find out how big the two strings are */
lenSource = stringLength (source);
lenS = stringLength (s);
/* sanity check here -- note that i == lenSource
effectively concatenates s onto the end of source */
if (i > lenSource)
return;
/* now we have to move the characters in source
down from the insertion point to make room for s.
Note that we copy the string starting from the end
to avoid overwriting characters in source.
We also copy the terminating null (j starts at lenS)
as well since the final result must be null-terminated */
for ( j = lenSource; j >= i; --j )
source [lenS + j] = source [j];
/* we've made room, now copy s into source at the
insertion point */
for ( j = 0; j < lenS; ++j )
source [j + i] = s[j];
}
There's an error somewhere in your insertString function where it goes out of bounds. By the way your insertString function doesn't start with the word void.
If I substitute the insertString function which I wrote for the exercise then the program works.
#include<stdio.h>
#include <string.h>
void insertString (char source[], const char s[], int start)
{
int stringLength (const char s[]);
int lenSource = strlen (source);
int lenString = strlen (s);
int i;
if ( start > lenSource ) {
printf ("insertion point exceeds string length\n");
return;
}
// move the characters in the source string which are above the
// starting point (including the terminating null character) to make
// room for the new characters; to avoid overwriting characters the
// process begins at the end of the string
for ( i = lenSource; i >= start; --i )
source[i + lenString] = source[i];
// insert new characters
for ( i = 0; i < lenString; ++i )
source[start + i] = s[i];
}
void readLine(char buffer[])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
int main(void)
{
char input[81];
char insert[81];
int position;
printf("Enter the first string: ");
readLine(input);
printf("Enter the insert string: ");
readLine(insert);
printf("Enter placement position int: ");
scanf("%i", &position);
insertString(input, insert, position);
printf("The adjusted string is %s\n", input);
return 0;
}

Split string into INT array in c [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I got string containing numbers separated by spaces. Numbers can be single-digit, two-digit, or perhaps more-digit. Check the example.
"* SEARCH 2 4 5 12 34 123 207"
I don't know how long the string is (how many numbers it contains), so I cant initiate the array properly. The result should look like this:
array = {2,4,5,12,34,123,207}
Do you have any ideas how to perform this?
like this:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char *input = "* SEARCH 2 4 5 12 34 123 207";
int len = 0;
sscanf(input, "%*[^0-9]%n", &len);//count not-digits(The Number isn't negative)
char *p = input + len;
char *start = p;
int v, n = 0;
while(1 == sscanf(p, "%d%n", &v, &len)){
++n;//count elements
p += len;
}
int array[n];//or allocate by malloc(and free)
char *endp = NULL;
int i;
for(i = 0; i < n; ++i){
array[i] = strtol(start, &endp, 10);
start = endp + 1;
}
//check print
for(i = 0; i < n; ++i)
printf("%d ", array[i]);
puts("");
return 0;
}
You can try this approach. It uses a temporary buffer to hold the current integer that is being processed. It also uses dynamic arrays, to deal with different lengths of the string you want to process, and expands them when necessary. Although using strtok Would be better in this situation.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int
main(int argc, char *argv[]) {
char message[] = "* SEARCH 2 4 5 12 34 123 207";
char *buffer = NULL;
int *integers = NULL;
int buff_size = 1, buff_len = 0;
int int_size = 1, int_len = 0;
int ch, messlen, i, first_int = 0;
/* creating space for dynamic arrays */
buffer = malloc((buff_size+1) * sizeof(*buffer));
integers = malloc(int_size * sizeof(*integers));
/* Checking if mallocs were successful */
if (buffer == NULL || integers == NULL) {
fprintf(stderr, "Malloc problem, please check\n");
exit(EXIT_FAILURE);
}
messlen = strlen(message);
/* going over each character in string */
for (ch = 0; ch < messlen; ch++) {
/* checking for first digit that is read */
if (isdigit(message[ch])) {
first_int = 1;
/* found, but is there space available? */
if (buff_size == buff_len) {
buff_size++;
buffer = realloc(buffer, (2*buff_size) * sizeof(*buffer));
}
buffer[buff_len++] = message[ch];
buffer[buff_len] = '\0';
}
/* checking for first space after first integer read */
if (isspace(message[ch]) && first_int == 1) {
if (int_size == int_len) {
int_size++;
integers = realloc(integers, (2*int_size) * sizeof(*integers));
}
integers[int_len] = atoi(buffer);
int_len++;
/* reset for next integer */
buff_size = 1;
buff_len = 0;
first_int = 0;
}
/* for last integer found */
if (isdigit(message[ch]) && ch == messlen-1) {
integers[int_len] = atoi(buffer);
int_len++;
}
}
printf("Your string: %s\n", message);
printf("\nYour integer array:\n");
for (i = 0; i < int_len; i++) {
printf("%d ", integers[i]);
}
/* Being careful and always free at the end */
/* Always a good idea */
free(integers);
free(buffer);
return 0;
}
You can read each character and verify if it is in range of >=48(Ascii of 0) and less than = 57(Ascii of 9). If so is the case read them into a array Otherwise you could copy them to a temporary string and convert to int using functions like atoi()
#include <stdio.h>
int main(int argc, char *argv[])
{
int j=0,k,res;
char buff[10];
while(str[j])
{
if((str[j]>='0')&&(str[j]<='9'))
{
k=0;
while((str[j]!=' ')&&(str[j]!='\0'))
{
buff[k]=str[j++];
k++;
}
buff[k]=0;
res=atoi(buff);
//Store this result to an array
}
j++;
}
return 0;
}

C string to array -uppercase character bug [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Given this string "red, blue, green" create an array that contains these colors as its elements. The code I've written below works but when I change the first letter of the colors to uppercase I get the output- Red, Blu\301-!Wree\316. How can I make this code more dynamic to work with words that start with uppercase as well? Thank you.
#include <stdio.h>
#include <stdlib.h>
int findLength(char string[]){
int l =0;
for(l = 0; string[l]!='\0'; l++){
}
return l;
};
char *stringToArray(char string[]){
int i = 0;
int j = 0;
char c = ',';
int n = 0;
int l = findLength(string);
char *str = (char *)malloc(l * sizeof(char));
while(string[i] != l){
if(string[i] == c || string[i] != '\0'){
for(n = j; n < i; n++){
str[j++] += string[n];
}
}
i++;
}
printf("%s\n", str);
str = '\0';
return str;
}
int main(int argc, const char * argv[]) {
char *string = "red, blue, green";
//char *string = "Red, Blue, Green";
char *str = stringToArray(string);
free(str);
return 0;
}
The strange behaviour doesn't have anything to do with whether your strings have upparcase letters or not. Your termination condition for the loop in stringToArray is wrong:
int l = findLength(string);
while (string[i] != l) ...
The condition should be
while (i < l) ...
or, as you have already used in findLength:
while (string[i] != '\0') ...
Because the condition is wrong – l is 16 in your case and none of the letters have an ASCII value of 16 – you go beyond the valid bounds of the string, which leads to undefined behaviour.
At the moment, you just copy the old string to the new one, albeit in a very strange fashion. Your inner loop makes use of three variables, of which it increments two. That's very confusing. It probably also doesn't do what you think, because the condition:
if (string[i] == c || string[i] != '\0') ..
is true for all letters of the string, provided that the opuer loop should consider only valid characters up to, but not including the end of the string.
Finally, if you want to copy the string, you should allocate süpace for the terminating character:
char *str = malloc(l + 1);
When you want to append the final null character:
str = '\0';
You actually set the while allocated string to null, which leads to a memory leak. (The free in main doesn't produce an error, because free can legally take ´NULL` as argument.) Instead, use:
str[l] = '\0';
With these fixes, you now have a program that copies the original string. The (POSIX) library function strdup does this more effectively. If you want to return an array of strings, you must reflect your function to return a pointer to pointers of chars.
Below is a possible implementation of that behaviour. (It uses the approach to allocate memory for everything on the heap. If you always expect three short strings that may not be the best solution.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **stringToArray(const char *str)
{
char **res;
const char *p = str;
int n = 0;
while (p) {
p = strchr(p, ',');
if (p) p++;
n++;
}
res = malloc((n + 1) * sizeof(*res));
p = str;
n = 0;
while (p) {
const char *begin;
size_t len;
while (*p == ' ') p++;
begin = p;
p = strchr(p, ',');
if (p) {
len = p - begin;
p++;
} else {
len = strlen(begin);
}
res[n] = malloc(len + 1);
memcpy(res[n], begin, len);
res[n][len] = '\0';
n++;
}
res[n] = NULL;
return res;
}
int main(int argc, const char * argv[])
{
char *str = "Vermilion, Ultramarine, Chartreuse";
char **res = stringToArray(str);
int i = 0;
for (i = 0; res[i]; i++) {
puts(res[i]);
free(res[i]);
}
free(res);
return 0;
}
you have a few mistakes...
I've corrected them for you:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int findLength(char string[]){
int l = 1;
for (int i = 0; string[i] != '\0'; i++){
if (string[i] == ',')// to check the end of a color
l++;
}
return l;
};
char **stringToArray(char string[]){//added a * for array of satrings
int i = 0;
int j = 0;
char c = ',';
int n = 0;
int l = findLength(string);
char **str = (char **)malloc(l * sizeof(char*)+l);
char *pos = string;
for (int i = 0; i < l-1; i++) //getting each color to the array
{
char *c =strchr(string, ',');
int index = c - pos;
string[index] = 0;
str[i] = _strdup(pos); //copying the color to the array
pos = c + 1;
string = string +1 +index; // next color
}
str[l - 1] = _strdup(pos); //copying last color
for (int i = 0; i < l; i++) //printing the results
{
printf("%s\n",str[i]);
}
return str;
}
int main(int argc, const char * argv[]) {
char string[] = "red,blue,green"; //deleted spaces
char **str = stringToArray(string);
getchar();
free(str);
return 0;
}
also added comments for you to understand.

Resources