C 가장 긴 행 출력하는 프로그램 질문좀 드려요

xodn158의 이미지

main 함수를 시작하고 getline 함수 자체에서 먼저 문자열을 입력받고 이후에 getline 함수로 가서 작업을 처리하는 거 맞나요?
그런데 getline 함수에서 int c 를 선언하고 for 의 조건연산에 (c = getchar()) != 0 을 한 이유를 모르겠습니다.
사실 함수 전체가 이해가 안됩니다..

#include <stdio.h>
#define MAXLINE 1000
 
int getline(char line[], int maxline);
void copy(char to[], char from[]);
 
int main() {
 
	int len, max = 0;
	char line[MAXLINE];
	char longest[MAXLINE];
 
	while ((len = getline(line, MAXLINE)) > 0) {
		if (len > max) {
			max = len;
			copy(longest, line);
		}
		if (max > 0)
			printf("가장 긴 행 = %s", longest);
	}
	return 0;
}
int getline(char s[], int lim)
{
	int c, i;
	for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) 
		s[i] = c;
		if (c == '\n') {
			s[i] = c;
			++i;
		}
			s[i] = '\0';
 
			return i;
 
}
void copy(char to[], char from[])
{
	int i;
	i = 0;
	while ((to[i] = from[i]) != '\0')
		++i;
}

shint의 이미지

//소스 설명
데이터를 계속 입력하는데.
이전에 입력한 데이터보다. 글자 수 가 많으면. 최대값을 저장해둡니다.를 반복...

//
len = getline() 의 리턴값 == 데이터의 문자열의 길이(갯수)
line = getline() 에서 얻어온 데이터 값
max = 입력된 갯수중에서 가장 큰 길이(갯수)를 덮어쓴 값
longest = getline() 에서 얻어온 line 데이터 값을 입력
copy(~로, ~에서); ~에서 ~로 데이터 입력
getline(얻어올 line 데이터 값, 입력할 최대 갯수)

//
스크래치 프로그램으로 구조를 만들어 봤습니다.
https://scratch.mit.edu/projects/221185122/

0을 입력하면. 값이 초기화 됩니다.

//
아래 소스는.
C++ 에서 지원하는 getline() 함수와 같은 함수를 getchar() 함수로 만들었나봅니다.

//
구름 IDE 에서 연습이 가능합니다.
https://ide.goorm.io

#include <iostream>
 
 
using namespace std;
 
 
#define MAXLINE 100
 
int getline(char line[], int maxline);
void copy(char to[], char from[]);
 
 
int main(int argc, char* argv[])
{
 
	int len, max = 0;
	char line[MAXLINE];
	char longest[MAXLINE];
 
	while ((len = getline(line, MAXLINE)) > 0) {
		if (len > max) {
			max = len;
			copy(longest, line);
		}
		if (max > 0)
			printf("가장 긴 행 = %s\n", longest);
	}
	return 0;
}
int getline(char s[], int lim)
{
	int c, i;
	for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) 
		s[i] = c;
		if (c == '\n') {
			s[i] = c;
			++i;
		}
			s[i] = '\0';
 
			return i;
 
}
void copy(char to[], char from[])
{
	int i;
	i = 0;
	while ((to[i] = from[i]) != '\0')
		++i;
}

//출력 결과
root@goorm:/workspace/test4# mkdir -p /workspace/test4/bin/ && g++ $(find /workspace/test4/src/ -name *.cpp -o -name *.c) -o /workspace/test4/bin//main -g -std=c++11 -lm && /workspace/test4/bin//main

123 가장 긴 행 = 123
123 가장 긴 행 = 123
12 가장 긴 행 = 123
1234 가장 긴 행 = 1234
123456 가장 긴 행 = 123456
123 가장 긴 행 = 123456

//C++ 에서 지원되는 getline() 함수
std::getline (string)
http://www.cplusplus.com/reference/string/string/getline/
C++98
C++11
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

세벌의 이미지

C 언어 기초 공부를 차분하게 해 보셔요. C 언어 기초 책을 하나 보면서 하는 게 좋겠네요.

(c = getchar()) != EOF

getchar() 함수는 한 글자 입력 받는 함수.
입력받은 글자를 변수 c에 저장.

http://itguru.tistory.com/44
https://www.joinc.co.kr/w/man/3/getchar
등 참고해 보셔요. 모르면 또 질문 하시고...

EOF 에 대해서는
https://softwareengineering.stackexchange.com/questions/197625/storing-the-eof-end-of-file-character-in-a-char-type?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
참고해 보셔요.

xodn158의 이미지

if (c == '\n') {
s[i] = c;
} 이 작업을 해줬는데
s[i] = '\0'; 이것은 왜 해주는거죠?
이렇게 되면
애초에 if문을 안써도 되지않나요?

세벌의 이미지

들여쓰기 (indentation)을 이상하게 하신 것 같습니다.
{ 와 } 를 쓸 곳에 안 쓰셨거나...
이러면 소스 분석 어려워집니다.

if (c == '\n') {
			s[i] = c;
			++i;
		}

이것을 for 블럭 안에 넣고 싶은 건지? 아닌지?

getline 함수에서 무엇을 하고 싶은 건가요?

xodn158의 이미지

책에 나와있는데 헷갈려서 여쭤본거에요.. { } 이것도 제가 전부 쓴거고

세벌의 이미지

님께서 올린 소스코드가 어디선가 본 거 같다 했더니 The C programming language 2판이네요.
그 책 참 좋은 책인 거는 맞는데... 초보자가 보기 쉬운 내용은 아닙니다.

(저도 오랜만에 소스코드 타이핑 해 봤네요. 제가 친 거 오타 있을 수도 있습니다.)

#include <stdio.h>
#define MAXLINE 1000
 
int getline(char line[], int maxline);
void copy(char to[], char from[]);
 
int main()
{
	int len;
	int max =0;
	char line[MAXLINE];
	char longest[MAXLINE];
 
	while((len = getline(line, MAXLINE)) > 0)
		if(len > max) {
			max = len;
			copy(longest, line);
		}
	if (max > 0)
		printf("%s", longest);
	return 0;
}
 
int getline(char s[], int lim)
{
	int c, i;
 
	for(i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i]=c;
	if(c=='\n'){
		s[i]=c;
		++i;
	}
	s[i]='\0';
	return i;
}
 
void copy(char to[], char from[])
{
	int i =0;
 
	while( (to[i] = from[i]) != '\0')
		++i;
}

제가 들여쓰기 얘기한 까닭은 그러지 않으면 헷갈리기 때문입니다. 님께서 쓴 코드를 보면

if (c == '\n') {
	s[i] = c;
	++i;
}

이 부분이 for 안에 들어가는 거로 착각하기 쉽습니다.
제가 쓴 코드와 들여쓰기를 비교해 보셔요.

님께서 하신 질문에 대해 답을 드려야겠죠?
if 문 안써도 되느냐는 질문에는 "써야 됩니라"라고 답변 드립니다.
if 안에서 ++i 까지 하는 게 핵심.

s[i] = '\0'; 

이것은 왜 해주는거죠?
에 대한 답은 다른 분이 해 주셨네요.

기초 책 보라는 답변에 기죽어서 질문 다시는 못하실까 살짝 걱정되는데, 질문 계속 하셔도 됩니다 :)

익명 사용자의 이미지

문자열의 끝 이라고 표시(?)하기위해 NULL값을 입력 하는 것입니다.

/0 , null 차이는 ( https://kldp.org/node/28150 ) 이거 보시고,

먼저 C언어 기본책을 구하셔서 기초 공부를 먼저 하셔야 할 것 같습니다.

세벌의 이미지

getline 함수에서 int c 를 선언한 까닭

변수 c에 한 글자를 넣기 위해서.

char 가 아니고 int 를 쓴 까닭은? EOF 가 int 타입이라서.

https://stackoverflow.com/questions/18013167/why-must-the-variable-used-to-hold-getchars-return-value-be-declared-as-int?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

세벌의 이미지

the c programming language 2nd edition
구글에서 검색해 보니 책 한 권을 pdf 로 올려 놓은 게 있네요.

https://www.google.co.kr/search?q=the+c+programming+language+2nd+edition&oq=the+c+programming+language+2nd+edition&aqs=chrome.0.69i59j0l5.4771j1j7&sourceid=chrome&ie=UTF-8

http://www.dipmat.univpm.it/~demeio/public/the_c_programming_language_2.pdf

영어이긴 하지만 너무 어려워하진 마시고요.(영어가 어려운 게 아니라 책 내용이 어려울 겁니다...)
해당 부분 찾아서 설명을 잘 읽어보시고...
한국어 번역본 책으로 공부하시는 거 같은데 원문과 어떤 차이가 있나도 비교해보시고...
모르면 kldp든 어디에든 물어보다 보면 하나씩 하나씩 해결해 갈 수 있을 겁니다.

한국어 번역본 pdf 파일을 올려놓은 곳이 있는지는 모르겠네요. 아마 없을 거 같네요...

xodn158의 이미지

책은 이미 샀어요 ㅋㅋ 괜찮은 책이라고 해서 샀는데 확실히 수준이 높네요. 설명도 넘어가는게 많고.. 답변해줘서 감사합니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.