I am trying to get rid of all \ characters in a string in C. For example, if a string is co\din\g it should convert the string to coding.
So far I have the code
for(i = 0; i < strlen(string); ++i){
if(string[i] == '\'){
}
}
That looks to see if there is a backslash. I don't know how I would do to remove the backslash, however. My only idea is to set the next character equal to the current character, however, I don't know how changing the length of the string would work with memory.
like this:
#include <stdio.h>
int main(){
char st[] = "co\\din\\g";
int k = 0;
for (int i = 0; st[i] != '\0'; ++i)
if (st[i] != '\\')
st[k++] = st[i];
st[k] = '\0';
fputs(st, stdout);
return 0;
}
This works. Since you're only deleting characters, you can write back into the same string. At the end, the termination '\0' will move to a lower index, and the rest of the array will simply be ignored by printf. Also, \ is the escape character, so to pass the \ itself you must write \\.
#include <stdio.h>
void nukechar(char s[], char c)
{
size_t j = 0;
for (size_t i = 0; s[i] != '\0'; ++i) {
if (s[i] != c) {
s[j] = s[i];
++j;
}
}
s[j] = '\0';
}
int main(void)
{
char s[200];
while (fgets(s, 200, stdin) != NULL) {
nukechar(s,'\\');
printf("%s", s);
}
return 0;
}
The simplest solution would be to use a second string for the result:
#include <stdio.h>
#include <string.h>
int main(void)
{
char result[100] = {'\0'}, string[] = "co\\din\\g";
for(int i = 0, j = 0; i < strlen(string); i++)
{
if(string[i] != '\\')
result[j++] = string[i];
}
printf("%s %s\n", result, string);
return 0;
}
Result
$ gcc main.c -o main.exe; ./main.exe;
coding co\din\g
Note
It is necessary to use double backslashes, \\, so the character following the backslash is not interpreted as an escape sequence.
Related
I'm learning C and I've a problem with this school homework.
I have to make function which get two strings from user as parameters. The function removes all spaces from the first string and returns the "cleaned" strings as the other parameter.
The main function ask three strings, uses function to remove spaces and prints "cleaned" strings.
My code doesn't work as it should? What goes wrong?
#include <stdio.h>
void removeSpaces(char *, char *);
int main(){
int i, j;
char string[101], strings[1][101];
for(i = 0; i <= 2; i++){
fgets(string, 100, stdin);
for(j = 0; string[j] != '\0'; j++){
strings[i][j] = string[j];
}
strings[i][j] = '\0';
removeSpaces(strings[i], strings[i]);
}
for(i = 0; i <= 0; i++){
for(j = 0; j <= 101; j++){
printf("%c", strings[i][j]);
}
}
}
void removeSpaces(char *string1, char *string2){
int i, j;
for(i = 0; string1[i] != '\0'; i++){
if(string1[i] != ' '){
string2[i] = string1[j];
j++;
}
}
string2[i] = '\0';
}
You have to be more careful when writing code. There are several things wrong:
In removeSpaces(), you never initialize j. So it can be anything.
You are also mixing up i and j inside removeSpaces(). i should only be used to index string1, and j only for string2.
strings[1][101] is only one string, not 3. But the first for-loop in main() runs 3 times.
You don't have to print strings character by character, just printf("%s", strings[i]) or fputs(strings[i], stdout).
I'm not sure why you used a two-dimensional array strings here. You only need two strings. Renaming the variables can also help you avoid getting confused. Consider:
#include <stdio.h>
static void removeSpaces(const char *input, char *output) {
int i, o;
for(i = 0, o = 0; input[i] != '\0'; i++) {
if(input[i] != ' ') {
output[o] = input[i];
o++;
}
}
output[o] = '\0';
}
int main() {
char input[100], output[100];
fgets(input, sizeof input, stdin);
removeSpaces(input, output);
fputs(output, stdout);
}
I want to replace every backslash in a string with two backslashes.
I use this code:
#include <stdio.h>
int main()
{
int iD, iM, iY = 0;
char str[255] = "C:\\Users\\Documents";
printf("%s \n", str);
int i = 0;
for(i = 0 ; i < (unsigned)strlen( str ) ; i++)
{
if ( str[i] == '\\')
{
str[i] == "\\\\";
}
}
printf("%s", str);
return 0;
}
Output : C:\Users\Documents
Expected Result : C:\\Users\\Documents
You can't simply replace a single character with two characters! The simplest way to achieve your result is to have a second string, then copy from old to new, one character at a time, adding an extra backslash when that is the character just copied.
Here's a working sample that does this:
#include <stdio.h>
#include <string.h>
int main()
{
char str[255] = "C:\\Users\\Documents";
char newstr[ 2 * sizeof(str) ]; // As suggested by "chux" - ensure buffer is big enough!
printf("%s \n", str);
int i, j;
for (i = j = 0; i < (int)strlen(str); i++, j++) {
newstr[j] = str[i];
if (str[i] == '\\') newstr[++j] = '\\'; // Insert extra backslash
}
newstr[j] = '\0'; // We need to add nul-terminator!
printf("%s", newstr);
return 0;
}
Of course, you could always replace the original string with the new one, once you've done the transformation, with a simple strcpy(str, newstr); line.
I have been trying to remove the repeated consecutive characters from a string using c language for an assignment.
The input is like: sheeeiiisccommminng
The output must be like: sheiscoming
But I am getting the output: sheiscomng
I am not able to find out what went wrong here, please give your valuable insights.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main() {
char str[100];
int i, j, k, len;
printf("Enter any string: ");
fgets(str, 100, stdin);
len = strlen(str);
for (i = 0; i < len; i++) {
j = i + 1;
k = i + 2;
while (j < len) {
if (str[j] == str[i]) {
j++;
} else {
str[k] = str[j];
k++;
j++;
}
}
len = k;
}
printf("\nString after removing characters:");
for (i = 0; i < len; i++) {
printf("%c", str[i]);
}
}
You should update the length of the string with len = k; after the end of the for loop.
Note however that you should also set a null terminator at the new length when you shorten the string to make it a proper C string.
Here is a simpler version:
#include <stdio.h>
int main() {
char str[100];
int i, j;
printf("Enter any string: ");
if (fgets(str, sizeof str, stdin)) {
for (i = j = 0; str[i] != '\0'; i++) {
if (j == 0 || str[j - 1] != str[i]) {
str[j] = str[i];
j++;
}
}
str[j] = '\0';
printf("String after removing characters: %s\n", str);
}
return 0;
}
Not sure about your code but you could do something like
char str[]="sheeeeisssscommmiingg";
int i, j;
for(i=j=0; str[j]; i++)
{
str[i]=str[j];
for(j++; str[j]==str[i]; ++j);
}
str[i]=`\0`;
printf("\n%s", str);
After examining a character in the string via the outer loop, subsequent characters which are the same are skipped using the inner for loop.
The original string is overwritten.
At the end, the nul terminator is added to the end of the new string.
Also consider reading this.
Output in this case is:
sheiscoming
In the str char array below I would first like to locate the first math symbol I see, then I would like to count backwards and remove whatever is between the previous three "_" and remove the three "_". Can I please get some ideas on how to do this?
So this:
xa_55_y_*_z_/_+_x_+
Should turn into:
xa*_z_/_+_x_+
My problem is I don't know how to remove:
_55_y_
Here is the code so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
char str [] = "xa_55_y_*_z_/_+_x_+";
int length = 0;
int decrementor = 0;
int underscore_counter = 0;
int i = 0;
length = strlen (str);
for(i = 0; i < length; i++)
{
decrementor = 0;
underscore_counter = 0;
if(str[i] == '*' || str[i] == '/' || str[i] == '+' || str[i] == '-')
{
decrementor = i;
while(underscore_counter != 3)
{
if(str[decrementor] == '_')
{
underscore_counter++;
printf("underscore_counter is %d \n", underscore_counter);
}
decrementor--;
}
}
}
return 0;
}
You can use strcspn() to find the first operator, which simplifies the problem a little. Then it's just a matter of going backwards and counting the underscores, and then just a matter of outputting the appropriate substrings, e.g.:
int main()
{
char str [] = "xa_55_y_*_z_/_+_x_+";
size_t firstOp = strcspn(str, "*/+-");
size_t len = strlen(str);
size_t i = firstOp;
int underscores = 0;
// go backwards looking for the underscores (or the beginning of the
// string, whichever occurs first)
while (i > 0)
{
if (str[--i] == '_')
underscores++;
if (underscores == 3)
break;
}
// output the first part of the string up to the third underscore
// before the first operator
for (size_t j = 0; j < i; j++)
putchar(str[j]);
// output the rest of the string after and including the operator
for (size_t j = firstOp; j < len; j++)
putchar(str[j]);
// and a linefeed character (optional)
putchar('\n');
}
Sorry for the poorly named i and j variables, hopefully it makes sense.
I basically have want to remove all the leading whitespace before the first valid character in an array.
For example if I have something like ' 1.6, 1.7', I want it to be '1.6, 1.7' or if it was just '1.7, 1.8', then it would be '1.7, 1.8'
This is my method for the whitespace, however it only shows where the whitespace are. I need help removing it.
char **storeArray
void Students::removeSpace()
{
int MAX_SIZE = 30;
for(int i=0; i<3; i++)
{
for(int j=0; j<MAX_SIZE; j++)
{
if(isspace(storeArray[i][j]) && !(isspace(storeArray[i][j++])
{
// I NEED HELP HERE. I'M TRYING TO REMOVE ALL THE LEADING WHITESPACE ONLY
}
}
}
}
To remove extra white-space, march through the string:
void Remove_Leading_ExtraMiddle_Trailing_Whitespace(char *s, int size) {
char *end = &s[size];
char *t = s;
// skip leading
while (isspace(*s))
s++;
// middle
for (;;) {
while (!isspace(*s) && *s != '\0') {
*t++ = *s++;
}
if (*s == '\0')
break;
*t = *s++;
while (isspace(*s))
s++;
if (*s == '\0') {
break;
}
t++;
}
// end
while (t < end) {
*t++ = '\0';
}
}
void removeSpace() {
int MAX_SIZE = 30;
char storeArray[4][MAX_SIZE];
for (int i = 0; i < 3; i++) {
Remove_Leading_ExtraMiddle_Trailing_Whitespace(storeArray[i], MAX_SIZE);
}
}
Try something like this:
#include <stdio.h>
int main()
{
char storeArray[20] = " Check it out.";
int whitespace = 0;
printf("%s\n", storeArray);
//Count leading whitespace
for(int i=0; i<20; i++)
{
if(storeArray[i] == ' ' || storeArray[i] == '\t')
whitespace++;
else
break;
}
//Shift everything left
for(int i=0; i<20; i++)
{
if (i+whitespace < 20)
storeArray[i] = storeArray[i+whitespace];
else
storeArray[i] = 0;
}
printf("%s\n", storeArray);
return 0;
}
If you're sure that the c-strings are not longer than MAX_SIZE and if they are null terminated strings:
for(int i=0; i<3; i++)
{
int j=0;
while (j<MAX_SIZE && isspace(storeArray[i][j])
j++;
if (j==MAX_SIZE) // oops ! Not null terminated and only whitespace ?
storeArray[i][0]='\0';
else if (j>0) // if no leading whiespace do nothing !
strcpy (storeArray[i], &storeArray[i][j]); // if you like c style
}
If you are working in C++ (as the Student::removeSpace() suggest), and if you really don't want to work with std::string, then you could consider replace all this with:
for(int i=0; i<3; i++)
copy(find_if(storeArray[i], storeArray[i] + MAX_SIZE, [](char c){ return c && !isspace(c); }), storeArray[i] + MAX_SIZE, storeArray[i]);
Edit: If you want to avoid moving your strings, and if you can afford to change the string pointers (i.e.you didn't dynamically allocate the strings), then you could do as well:
for(int i=0; i<3; i++)
for (int j=MAX_SIZE-1; j>=0 && isspace(*storeArray[i]); j--)
storeArray[i]++; // no move or copy, but original pointer lost forever
You can either keep strtrimws as a separate function or incorporate its contents within your Students::removeSpace function. The following function can be used with or without assigning the return. Examples: strtrimws (somestring); or char *newstring = strtrimws (somestring); Also note, while the original string 's' is modified by the function, the start address for 's' is unchanged making it safe for use with dynamically allocated strings. Shown below in context with your removeSpace function:
#include <ctype.h>
/** remove leading and trailing whitespace, original not preserved.
* this funciton can be used with or without assigning the return.
*/
char *strtrimws (char *s)
{
char *sp = s; /* start pointer to return */
char *p = s; /* pointer to parse string */
while (isspace (*s)) s++; /* skip leading whitespace */
while (*s) *p++ = *s++; /* reindex s to end */
while (isspace (*p)) *p-- = 0; /* null-terminate from end */
return sp;
}
char **storeArray;
void Students::removeSpace()
{
int i = 0;
for(int i=0; i<3; i++)
strtrimws (storeArray[i]);
}
NOTE: if you have initialized all pointers to zero/NULL in storeArray before assigning strings to (some or all) of the pointers-to-char you can simplify/improve removeSpace by eliminating the hardcoded number of iterations for i and replacing it with a simple:
void Students::removeSpace()
{
int i = 0;
while (storeArray[i])
strtrimws (storeArray[i++]);
}
Example of funciton in use:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/** remove leading and trailing whitespace, original not preserved.
* this funciton can be used with or without assigning return.
*/
char *strtrimws (char *s)
{
char *sp = s; /* start pointer to return */
char *p = s; /* pointer to parse string */
while (isspace (*s)) s++; /* skip leading whitespace */
while (*s) *p++ = *s++; /* reindex s to end */
while (isspace (*p)) *p-- = 0; /* null-terminate from end */
return sp;
}
int main (int argc, char **argv)
{
if (argc < 2) {
fprintf (stderr, "\n error: insufficient input. Usage: %s char* char* ... (max 5)\n\n", argv[0]);
return 1;
}
char array[5][50] = {{0}};
int i = 0;
for (i = 1; i < argc; i++)
{
strncpy (array[i-1], argv[i], strlen (argv[i]));
printf ("\n array[%d] '%s'\n", i, strtrimws (array[i-1]));
}
return 0;
}
output:
$ ./bin/stripwsarray " string 1 ws " " string 2 ws " " string 3 ws "
array[0] 'string 1 ws'
array[1] 'string 2 ws'
array[2] 'string 3 ws'