[완료]문자열을 반환값으로 받으려는데 null로 됩니다.

-@Naver의 이미지

vmware 우분투 64비트 18.04 버전입니다.

문자열의 크기가 지정된 크기보다 작으면 (크면 오버플로우 때문에 값이 꼬입니다ㅠㅠ)
문자열 값으로 입력받아서 in_id가 아닌 다른 함수에서 strncpy문으로 돌리려는데,
입력 및 복사(strncpy)로 받은 id 값이 없어집니다.
id 값을 저장?받아서 쓰려면 어떻게 해야 하는지, 모르겠습니다. 도와주세요ㅠㅠ

#define _CTR_SECURE_NO_WARNINGS
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
// #define len 크기 지정은 실제크기+1 로 지정
#define ACCESSlen 2 
#define IDlen 2 // 편의상 짧게 변경하고 작업 중... 원래는 10으로 기록해야 함.
#define PWDlen 3 // 편의상 짧게 변경하고 작업 중... 원래는 514로 기록해야 함.
#define MAX 1024 // 입력받는 임시 문자열
 
void printBOF_gets(char str[], int strsize, int define_size) { 
// gets() 버퍼오버플로우 방지 : 재입력 요구 메시지 출력하는 함수
    printf("입력한 byte(s)는 %dbyte(s)입니다.\n", strsize-1);
    printf("입력 가능한 최대 길이 %dbyte(s)보다 %dbyes(s)가 초과됐습니다.\n",
define_size-1, strsize-define_size);
    printf("입력할 데이터를 다시 확인해보세요.\n");
}
 
char  in_id() {
    char id[IDlen] = { 0, };
    int strsize = 0; // 실제로 사용자에게 입력 받은 글자수를 확인
    char str[MAX] = { 0, };
 
    puts("input id(9bytes 보다 길면 다시 입력함):");
    gets(str);
    strsize = strlen(str)+1;
    if(strsize > IDlen) {
        printBOF_gets(str, strsize, IDlen);
        str[0] = '\0';
        in_id();
    }
    else {
    //if(strsize <= IDlen) {
        printf("%s", str); //출력 됨
        strncpy(id, str, IDlen-1);
        printf("%s", id); // 출력 됨
        return id;
    }
  printf("%s", id); // 아무것도 출력 안 됨.ㅠㅠ
}
 
int main() {
	in_id();
	return 0;
}
raymundo의 이미지

정상적으로 in에 데이터가 들어가는 else 블록에서는 바로 리턴해버리니까 마지막 printf를 아예 실행도 못 할 거고,

마지막 printf 가 호출되려면 if 블록을 거쳐가는 경로인데 그 경로에는 in 에 뭔가 채워지는 일이 없으니 실행해도 아무것도 안 나오겠죠.

혹시 if {} 안에서 재귀호출되는 in_id()안에서 in을 채워넣은 게 출력될 거라고 생각하셨다면 호출된 in_id의 in과 호출하는 in_id의 in 은 완전히 별개의 지역 변수입니다.

좋은 하루 되세요!

-@Naver의 이미지

매번 정성스런 답변 고맙습니다. 제게 많은 격려와 힘이 됩니다^^

if{} 에서 in_id()를 다시 호출하는 이유는
id 값 길이 제한보다 길게 입력받을 경우, 다시 id 값을 입력받기 위함입니다.
else{} 에서는 id를 입력한 사용자가 길이제한을 넘기지 않았기에 입력받은 문자열을 그대로 저장?받기 위함이고요. 그러면,,, 문자열을 저장? 받을 수 있는 방법은 없는지 궁금합니다.
만약…방법이 없다면… 그때는 if{} 부분을 아예 exit(0); 으로 종료시켜야 하나..고민 중입니다.

초보 C언어 학습자. 실력자분들의 도움이 절실합니다.

라스코니의 이미지

while(1) {
  if (ok)
     break;
}

이면 되지 않나요?
-@Naver의 이미지

말씀해주신대로 아래처럼 고쳐서 해결되었습니다. 고맙습니다.
while(1) {
puts("input id(9bytes 보다 길면 다시 입력함):");
gets(str);
strsize = strlen(str)+1;
if(strsize <= IDlen)
break;
printBOF_gets(str, strsize, IDlen);
}
strncpy(id, str, IDlen-1);

초보 C언어 학습자. 실력자분들의 도움이 절실합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.