質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.30%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2422閲覧

末尾の改行を削除するC/C++のコード

moomoomoo

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2022/10/28 16:44

編集2022/10/29 06:04

C言語で、入力された文字列の末尾にある改行を削除する関数removeEOLを以下のように実装しました。
しかし、これを実行すると、Segmentation faultが起きてしまいます。
main文のchar* str = "abc\n";char str[10] = "abc\n"などに変更した場合はSegmentation faultは起きず、正常に実行できます。
C++においても同様の問題が起きることを確認しています。

どうやら17行目のstr[endIndex] = 0x00でSegmentation faultが起きているようですが、ではなぜ16行目のif(str[endIndex] == 0x0a)ではSegmentation faultが起きないのでしょうか。
原因が全く分かりません。

ご回答いただければ幸いです。

#include <stdio.h> #include <string.h> void removeEOL(char* str) { int endIndex; int len = strlen(str); // 文字列長 if(len > 0) { endIndex = len - 1; } else { return; // 空文字の時は何もしない } // 末尾の改行コードを削除(LF,CR,CR+LF対応) if(str[endIndex] == 0x0a) { // LFの場合 str[endIndex] = 0x00; // NULLに置き換える endIndex--; // CR+LFの時用にインデックスを一つ戻す } if(str[endIndex] == 0x0d) { // CRの場合 str[endIndex] = 0x00; // NULLに置き換える } } int main(void) { char* str = "abc\n"; removeEOL(str); printf("%s\n", str); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2022/10/28 17:56

c と c++ は別の言語です。c の質問でしたらタグは c だけにしてください。
moomoomoo

2022/10/28 20:04

C++でも同じコードで動いて,かつ同じ問題が起きるので,C/C++両方に向けた質問であると考えているのですがおかしかったでしょうか? OSはUbuntu(WSL)です
jimbe

2022/10/29 04:03

件名に「Cのコード」と書かれていて、本文に「C言語で」と書かれており、「C++でも同じコードで動いて,かつ同じ問題が起きる」(起きていることを確認している)ことは、本文には何も書かれておりません。 その一文を本文にも追加して戴けますとタグと内容がより一致すると思いますが、如何でしょうか。
moomoomoo

2022/10/29 06:06

タイトルと本文でC++の場合についての記述を追加いたしました。 問題なかったでしょうか?
jimbe

2022/10/29 06:17

有難うございます。
guest

回答1

0

ベストアンサー

Cのリテラル文字列はreadonlyだから、書くと死ぬ。
書きたいなら一旦配列(とかmallocしたエリアとか)にいれる。

投稿2022/10/28 17:13

matukeso

総合スコア1685

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moomoomoo

2022/10/28 20:16

なるほど C言語の仕様として書き換えができないんですね 簡潔で分かりやすい回答で助かりました。 ありがとうございました。
thkana

2022/10/29 00:09

細かい話ですが、 > C言語の仕様として書き換えができない のではありません。C言語の仕様としては、リテラルの領域に書き込みを行った場合の動作は「未定義」、つまり何が起こるかを保証しない、です。 WindowsやUnix等の環境下であれば、リテラルがリードオンリーの領域に配置されていて(C言語ではなく、OSによって)Segmentation faultになるかも知れません。 昔のMS-DOS等のように、プログラムをRAM上に展開し、かつメモリ保護がないシステムであれば、何事もなかったかのようにリテラルが書き換えられるかも知れません(どうだったっけ?) 組み込みの、プログラムがROMになっているようなものであれば、エラーもなにもないけれどリテラルは書き換えられない、という結果になるかも知れません。 いずれにしても、「原則としてやってはいけない」操作であることは言えるのですが。
moomoomoo

2022/10/29 06:19

補足ありがとうございます。 少し理解が足りないまま納得してしまってました。 リテラルの扱いについて勉強する機会にもなりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問