#include <string.h> #include <stdio.h> #include <stdlib.h> #define N 20 int main(){ char M[N], M2[N]; int i,j; gets(M); for(i=0; M2[i] !='\0';i++){ M2[i]=' '; } M2[0]=M[0]; for (i=0; M[i] != '\0'; i++){ char n = M[i]; for (j=0; j=i; j++){ if (n!=M[j]){ M2[j]=n; }else{ for(int u=j;M[u]!='\0';u++){ M[u]=M[u+1]; } } } } for (i=0; M2[i] != '\0';i++) { printf ("%c", M2[i]); } } 

When I run the code, the compiler loops. According to the task you need to rewrite the string without duplicate characters.

  • You already have the first loop does not make sense, since the array M2 is not initialized. - Vlad from Moscow
  • in the nested cycle itself, the variable u goes through, but the variable j is checked - Alexey Obukhov
  • four
    Maybe you got into an infinite loop, in the line for (j = 0; j = i; j ++) {, where you perform an assignment instead of checking the condition. - Ivan Tsyganenko
  • one
    Learn to use the debugger, it helps in such cases - Vladimir Martyanov

4 answers 4

The gets function is not safe, and is no longer supported by the C standard. Instead, it is better to use the fgets function.

This cycle

  for(i=0; M2[i] !='\0';i++){ M2[i]=' '; } 

meaningless because the M2 array was not initialized.

In this cycle, you have an assignment instead of a comparison.

 for (j=0; j=i; j++){ ^^^^ 

In addition, the subsequent if-else clause does not make sense.

The program might look like this.

 #include <stdio.h> #include <string.h> #define N 20 int main(void) { char s1[N]; char s2[N]; printf( "Enter a string no more than %d characters: ", N ); fgets( s1, N, stdin ); s1[strcspn( s1, "\n" )] = '\0'; size_t i = 0; size_t j = 0; do { size_t k = 0; while ( k < j && s1[i] != s2[k] ) k++; if ( k == j ) { s2[j++] = s1[i]; } } while ( s1[i++] ); puts( s2 ); return 0; } 

Its output to the console may be

 Enter a string no more than 20 characters: AABBCCCDEFGGHHH ABCDEFGH 
  • I don’t quite understand why there are so many cycles and generally so much code? Here is an example in the form of a separate function size_t strcpy_norep(const char * s_in, char * s_out, size_t s_out_size){ char c, c_prev = 0, *ptr=s_out; while((c = *s_in++) ) if(c!=c_prev) *ptr++=(c_prev=c); *ptr = 0; return ptr-s_out; } size_t strcpy_norep(const char * s_in, char * s_out, size_t s_out_size){ char c, c_prev = 0, *ptr=s_out; while((c = *s_in++) ) if(c!=c_prev) *ptr++=(c_prev=c); *ptr = 0; return ptr-s_out; } size_t strcpy_norep(const char * s_in, char * s_out, size_t s_out_size){ char c, c_prev = 0, *ptr=s_out; while((c = *s_in++) ) if(c!=c_prev) *ptr++=(c_prev=c); *ptr = 0; return ptr-s_out; } - rst256
  • @ Dmitriy Evgenjevich Kholichev Your function considers only adjacent characters, whereas I presented a function that writes only unique characters to the resulting string. From the question it is not clear which of these approaches is required. Although the code presented in the question most likely implies that my approach is required, although I may be mistaken. - Vlad from Moscow
  • you may well be - rst256
  • ... right. But then why are there so many cycles? There are functions strchr and memchr, for example, something like this: `int c; char s [60] = "\ 0", * ptr = s, * ptr_end = s + sizeof (s) -1; while ((c = getchar ())! = '\ n') {if (! strchr (s, c)) {* ptr ++ = c; * ptr = 0; if (ptr> = ptr_end) {printf ("\ noverflow, max char count;% d \ n", sizeof (s) -1); break; }}} printf ("% s' \ n", s); `Only if the conditions of the assignment use strchr and memchr is impossible, but this condition is meaningless even when learning, why teach" reinvent the wheel "? - rst256

1) In the line for (j = 0; j=i; j++) change the test condition to j<i .

2) (note) If you write in C, then it is better to declare loop counter variables outside the loop instruction. I’m talking about the most nested loop with the counter int u=j say. Still, this is a plus trend more. Also, as noted in the comments, use the debugger to check the values ​​of variables at each iteration, namely, I recommend to figure out what a breakpoint is and what it eats with. For example, in MSVS it is very convenient, in my opinion, this detail is implemented. Also, for starters, you can use commands like "step by step", "step with detour" and so on. In such tasks it helps a lot.

    Here

      for (j=0; j=i; j++){ 

    already at i = 1

      I did it myself like this:

       #include <string.h> #include <stdio.h> #include <stdlib.h> #define N 20 int main(){ char M[N]; int i,j,u,k=0; gets(M); for (i=0; M[i]!='\0'; i++){ char n = M[i]; for (j=i+1; M[j]!='\0'; j++){ if (n==M[j]){ k++; for(u=j; M[u]!='\0'; u++){ M[u]=M[u+1]; } } } } for (i=0; M[i] != '\0';i++) { printf ("%c", M[i]); } printf ("\nKol-vo udalennyh symbols is = %i", k); } 

      So will it be right?

      • one
        You asked a question. You answered it. Do not ask new questions in the answers. This is misleading to read the question. If you have a new question, then create a new topic for it. - Vlad from Moscow