1

I'm doing a problem from Programming in C that requires me to make a program that takes a word, and a start position as well as number of words to take, and puts it into a result array. I've seen some solutions online, but they all use POINTERS, which I can't use, because we're not in that section yet.

#include <stdio.h>

char substring (char source[], int start, int count, char result[])
{
  int i;

  for (i = 0; (i < count) && (source[start + i] != '\0'); ++i)
  {
    result[i] = source[start + i];
  }

  result[i + 1] = '\0';

  return result;
}

int main (void)
{
  char substring (char source[], int start, int count, char result[]);
  char source[81];
  char result[81];
  int start, count;

  printf ("Enter the word you want to check!\n");
  printf ("And the start position as well as the number of words to count!\n");
  scanf ("%s %i %i", &source[81], &start, &count);

  printf ("Your result is: %s\n", substring(source, start, count, result));
}

I keep on getting errors when compiling and when I fix them I don't get a result. Thanks.

8
  • Does this code compile with or without errors? If with errors (or warnings), what are they? At this stage in your career, if the compiler warns, it means there's a problem you need to fix. Commented Oct 25, 2016 at 6:14
  • 2
    Note that &source[81] is a major problem; you're passing beyond the end of your array char source[81]; to scanf(). You need either &source[0] or just source there instead. Commented Oct 25, 2016 at 6:15
  • 1
    Your descriptions says "a start position as well as number of words to take, and puts it into a result array"; your code seems to be counting characters, not words. Which did you mean really? Commented Oct 25, 2016 at 6:17
  • Technically you use pointers too! When you declare a function argument like e.g. char source[] the compiler treats it as char *source. So in the substring function you don't have arrays, you have pointers. Commented Oct 25, 2016 at 6:20
  • 1) remove the prototype from the function main() for function: substring() 2) when calling any of the scanf() family of functions, always check the returned value (not the parameter values) to assure the operation was successful. 3) when calling scanf() and using the %s format specifier, always include a 'max characters' modifier that is one less than the length of the input buffer, to avoid any buffer overflow. Note: a buffer overflow is undefined behavior and can lead to a seg fault event. Commented Oct 26, 2016 at 21:45

3 Answers 3

2

When you pass &source[81] to the scanf function you pass a pointer to the 82:nd character in the array, which is out of bounds leading to undefined behavior.

You should pass a pointer to the first character in the array: &source[0].

Also note that &source[0] is equal to plain source since arrays naturally decays to pointers to their first element.

Sign up to request clarification or add additional context in comments.

Comments

1

Change

scanf ("%s %i %i", &source[81], &start, &count)

to

scanf ("%s %i %i", source, &start, &count)

Also in the function you are returning a char and trying to print it with a %s. You should return a char* for that. So, the function becomes,

char* substring (char source[], int start, int count, char result[])
{
  int i;

  for (i = 0; (i < count) && (source[start + i] != '\0'); ++i)
  {
    result[i] = source[start + i];
  }

  result[i + 1] = '\0';

  return result;
}

7 Comments

the proposed 'fix' for the call to scanf() still allows the user to overrun the input field, so this answer leaves a lot to be desired.
@user3629249 While I agree that scanf has some flaws, this post is not the place to point them out, The answer solved the issues faced by OP and was the first one to point out both issues.
The answer misleads the OP because it does not properly present how to handle a char array input from the user. It is not the scanf() function that is flawed, it is the proposed answer that is flawed. Simplest fix, edit the call to scanf() to properly input a char array.
@user3629249 Can you tell me what would be your solution?
the correction to the scanf() function would be: scanf ("%80s %i %i", source, &start, &count) Of course, using 'magic' numbers in the body of the code is never a good idea. suggest: ... #define MAX_CHAR_LEN (80) ... char source[ MAX_CHAR_LEN+1]; .... scanf ("%" MAX_CHAR_LEN "s %i %i", source, &start, &count)`
|
1

Do not declare/prototype the function inside main:

int main (void)
{
    char substring (char source[], int start, int count, char result[]);
    ...

Instead:

char substring (char [], int, int, char []);

char substring (char source[], int start, int count, char result[])
{
   ...

As stated by @Someprogrammerdude, you are passing the address of the last element of the array: &source[81] to scanf, you need to pass the address of the first element: &source[0] (or simply source), another problem is that you are returning a plain char where you want to return a string, change to

char *substring (char source[], int start, int count, char result[])

4 Comments

There is a prototype there. It isn't necessary to put it inside main() as well, but it is technically legal, and it isn't 'old C style' (in the normal sense of the term). You're right, too, that the function should return a char *.
@JonathanLeffler: Where is the prototype?
The function is defined using prototype notation; there is also a prototype in main().
@JonathanLeffler, yes I mean do not declare the prototype inside main, edited

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.