0

What I need to do is to put the first n of second string input behind first string input .And every string may have blank space which I donot know how to set formatted input. I try to do it like this.BUT wrong output.

void fun(char *s1, char *s2, int n){
    int l = strlen(s1);
    for(int i=0;i<n;i++){
    s1[l+i]=s2[i];}
}
int main(){ 
    char s1[10];char s2[10]; int n;
    scanf("%s\n",s1);
    scanf("%[^\n]",s2);
    scanf("%d",&n);
    fun(s1,s2,n);
    printf("%s",s1);
  return 0;
}

The output example:

hello
my bro
3
hellomy @
  • You need to manage the terminating `'\0'` properly for `s1` in `fun()` function. Also think about possible buffer overflows! – pmg Jul 19 '21 at 08:30
  • 2
    Use `fgets` instead of `scanf` – Support Ukraine Jul 19 '21 at 08:41
  • What if the second string has less characters than the specified number? Are you trying to implement `strncat`? What do you mean with "wrong output"? Please [edit] your question and show both the output you actually get and what you want to get. – Bodo Jul 19 '21 at 09:52

3 Answers3

0

The string handling functions in the C standard library is quite error prone so it's sometimes best to roll you own. Below is a solution which uses safe functions for reading a line of text and appending two strings.

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void ReadLine(char result[], int resultLen)
{
    int ch, i;

    assert(resultLen > 0);
    i = 0;
    ch = getchar();
    while ((ch != '\n') && (ch != EOF)) {
        if (i < resultLen - 1) {
            result[i] = ch;
            i++;
        }
        ch = getchar();
    }
    result[i] = '\0';
}


void Append(const char extra[], char dest[], int destLen)
{
    int i, j;

    i = 0;
    j = strlen(dest);
    while ((extra[i] != '\0') && (j + i < destLen - 1)) {
        dest[j + i] = extra[i];
        i++;
    }
    dest[j + i] = '\0';
}


int main(void)
{
    char s1[10], s2[10];
    int count, n;

    ReadLine(s1, sizeof s1);
    ReadLine(s2, sizeof s2);
    count = scanf("%d", &n);
    if ((count == 1) && (n >= 0)) {
        Append(" ", s1, sizeof s1);
        if (n < (int) sizeof s2) {
            s2[n] = '\0';
        }
        Append(s2, s1, sizeof s1);
        puts(s1);
    } else {
        fprintf(stderr, "Non-negative integer expected\n");
        exit(EXIT_FAILURE);
    }
    return 0;
}
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60
0

Your example add only 3 first chars from s2 ('m', 'y' and 'space') - this looks ok.

In void fun() you inserting part s2 on the end of s1 additionally overwriting '/0'. The output should looks:

"hellomy ", but you don't insert a null termination. So we see a:

"hellomy @", this happend because :s1[9] was '/0'

So in the worst case your edited s1 string could be without null termination. So function printf will prints characters until it finds any '/0' after start reading memory. so program could generate access violation error... Please consider protect string from exceed their dimension and proper null terminating...

Wojciech
  • 111
  • 2
0

There are two fundamental problems here. (Don't worry, they're problems with the C language, not with you or your program.)

  1. There is no good, easy way in scanf to read a string that might contain whitespace. (There's a way, which you tried, but it's confusing and has problems.)

  2. A program that calls scanf to read some input cannot reasonably call fgets or getchar to read other input. (Again, there are ways to make this work, but they're confusing and buggy and more trouble than they're worth.)

If you want to read a string that might contain whitespace, the only reasonable way to do it is to call fgets. But if your program calls fgets to read some stuff, it cannot easily call scanf to read other stuff. (In particular, the first time you use scanf("%d", &n) to read an integer, followed by fgets to read a line, you'e going to be back here on Stack Overflow asking why fgets mysteriously read a blank line.)

So what can you do? Use fgets to read everything. If you need a number, use fgets to read it as a string, then convert it to a number with atoi or strtol.

See also What can I use for input conversion instead of scanf? .

Steve Summit
  • 45,437
  • 7
  • 70
  • 103